From 177b7971654212bc4fae6292f0a470dca2a7775e Mon Sep 17 00:00:00 2001 From: Diptesh Choudhuri Date: Wed, 23 Oct 2024 14:24:09 +0530 Subject: [PATCH] Bidirectional Jellyfin sync (#1075) * chore(doc): change attributes * chore(backend): change name to jellyfin sink * refactor(services/integration): remove one layer of indirection * chore(gql): regenerate types * feat(backend): add new integration provider * chore(backend): change names of fields * feat(frontend): allow saving jellyfin push integration * chore(frontend): remove useless schema * chore(backend): add new event to handle media seen events * chore(backend): fn to handle deploying media seen event * refactor(backend): functions to deploy jobs * refactor(backend): break services a bit more * fix(services/importer): include token correctly * chore(services/integrations): scaffold stuff for new jellyfin push integration * chore(backend): add new crate for external stuff * refactor(backend): extract authentication stuff to new utils crate * feat(services/integrations): start with pushing progress to jellyfin * docs: add info about new push integration * fix(frontend): do not allow creating/disabling account access links If the currently active user is under a demo link. * fix(backend): use correct user agent str for headers * feat(frontend): make creating workout/template client side * fix(frontend): handle supersets when deleting exercise from workout * feat(frontend): change btn for editing superset * refactor(services/integrations): change names of structs * chore(backend): log the request * feat(services/integrations): send request to get movie * feat(services/integrations): allow searching for movie * feat(services/integrations): allow marking movie as played * chore(services/integrations): send info about which show was played * feat(services/integrations): allow marking shows as seen * feat(migrations): add new column for video games duration * chore(backend): add manual spent time to video game duration * feat(frontend): display total video game duration * fix(backend): add video game time to total duration * fix(migrations): add column if it does not exist * fix(services/statistics): use correct manual time spent * fix(services/statistics): use correct manual time spent * feat(frontend): make jellyfin push a pro feature * chore(ts): update all dependencies other than remix * chore(ts): upgrade conform deps * chore(website): upgrade to latest remix * chore(frontend): upgrade to latest remix * ci: Run CI * chore(frontend): use new utility function * refactor(frontend): remove usage of `namedAction` * refactor(frontend): move utility function to utils package * refactor(website): use new utility function --- Cargo.lock | 23 +- Cargo.toml | 1 + apps/backend/src/job.rs | 8 + apps/frontend/app/lib/utilities.server.ts | 15 +- apps/frontend/app/root.tsx | 10 +- .../frontend/app/routes/_dashboard._index.tsx | 15 +- .../app/routes/_dashboard.calendar.tsx | 14 +- .../_dashboard.collections.$id._index.tsx | 14 +- .../routes/_dashboard.collections.list.tsx | 33 +- .../app/routes/_dashboard.fitness.$action.tsx | 125 +- .../_dashboard.fitness.$entity.$id._index.tsx | 32 +- .../_dashboard.fitness.$entity.list.tsx | 14 +- .../_dashboard.fitness.exercises.$action.tsx | 54 +- ...oard.fitness.exercises.item.$id._index.tsx | 17 +- .../_dashboard.fitness.exercises.list.tsx | 15 +- .../_dashboard.fitness.measurements.list.tsx | 50 +- .../routes/_dashboard.media.$action.$lot.tsx | 9 +- .../app/routes/_dashboard.media.create.tsx | 16 +- .../_dashboard.media.genre.$id._index.tsx | 9 +- .../routes/_dashboard.media.genre.list.tsx | 14 +- .../_dashboard.media.groups.$action.tsx | 14 +- ...dashboard.media.groups.item.$id._index.tsx | 9 +- .../_dashboard.media.item.$id._index.tsx | 138 +- .../_dashboard.media.people.$action.tsx | 14 +- ...dashboard.media.people.item.$id._index.tsx | 10 +- ...rd.settings.imports-and-exports._index.tsx | 109 +- .../_dashboard.settings.integrations.tsx | 101 +- .../_dashboard.settings.miscellaneous.tsx | 12 +- .../_dashboard.settings.notifications.tsx | 46 +- .../_dashboard.settings.preferences.tsx | 21 +- ...dashboard.settings.profile-and-sharing.tsx | 57 +- .../app/routes/_dashboard.settings.users.tsx | 43 +- apps/frontend/app/routes/_dashboard.tsx | 8 +- apps/frontend/app/routes/actions.tsx | 11 +- apps/frontend/app/routes/api.auth.tsx | 6 +- .../app/routes/api.sharing.$accessLinkId.tsx | 6 +- apps/frontend/app/routes/auth.tsx | 45 +- .../app/styles/preferences.module.css | 2 +- apps/frontend/package.json | 64 +- apps/frontend/tsconfig.json | 3 +- apps/frontend/vite.config.ts | 8 +- .../app/lib/components/ui/carousel.tsx | 3 +- .../app/lib/components/ui/input-otp.tsx | 1 - apps/website/app/lib/config.server.ts | 12 +- apps/website/app/root.tsx | 17 +- apps/website/app/routes/_index.tsx | 77 +- apps/website/app/routes/auth.tsx | 39 +- apps/website/app/routes/callback.tsx | 6 +- apps/website/app/routes/me.tsx | 30 +- apps/website/app/tailwind.css | 129 +- apps/website/package.json | 74 +- apps/website/vite.config.ts | 10 +- crates/background/Cargo.toml | 1 + crates/background/src/lib.rs | 3 + crates/enums/src/lib.rs | 3 +- crates/migrations/src/lib.rs | 2 + .../m20240827_create_daily_user_activity.rs | 2 + .../src/m20241019_changes_for_issue_964.rs | 23 + .../database/src/daily_user_activity.rs | 1 + crates/models/media/src/lib.rs | 9 + crates/services/exporter/Cargo.toml | 1 - crates/services/exporter/src/lib.rs | 8 +- crates/services/fitness/Cargo.toml | 1 - crates/services/fitness/src/lib.rs | 18 +- crates/services/importer/Cargo.toml | 2 +- crates/services/importer/src/jellyfin.rs | 103 +- crates/services/importer/src/lib.rs | 8 +- crates/services/integration/Cargo.toml | 1 + crates/services/integration/src/lib.rs | 73 +- .../services/integration/src/push/jellyfin.rs | 90 + crates/services/integration/src/push/mod.rs | 1 + .../services/integration/src/push/radarr.rs | 42 +- .../services/integration/src/push/sonarr.rs | 42 +- crates/services/integration/src/sink/emby.rs | 13 +- .../integration/src/sink/generic_json.rs | 10 +- .../services/integration/src/sink/jellyfin.rs | 10 +- crates/services/integration/src/sink/kodi.rs | 10 +- crates/services/integration/src/sink/plex.rs | 10 +- .../integration/src/yank/audiobookshelf.rs | 4 +- crates/services/integration/src/yank/komga.rs | 10 +- crates/services/miscellaneous/Cargo.toml | 1 - crates/services/miscellaneous/src/lib.rs | 38 +- crates/services/statistics/src/lib.rs | 4 + crates/services/supporting/Cargo.toml | 1 + crates/services/supporting/src/lib.rs | 26 +- crates/services/user/src/lib.rs | 15 +- crates/utils/common/src/lib.rs | 2 +- crates/utils/database/Cargo.toml | 1 - crates/utils/database/src/lib.rs | 55 +- crates/utils/dependent/Cargo.toml | 1 - crates/utils/dependent/src/lib.rs | 129 +- crates/utils/external/Cargo.toml | 16 + crates/utils/external/src/lib.rs | 109 + docs/content/integrations.md | 48 +- docs/pyproject.toml | 2 +- libs/generated/package.json | 4 +- libs/generated/src/graphql/backend/gql.ts | 4 +- libs/generated/src/graphql/backend/graphql.ts | 11 +- .../src/backend/mutations/combined.gql | 215 +- .../backend/queries/CollectionContents.gql | 48 +- .../src/backend/queries/CoreDetails.gql | 28 +- .../src/backend/queries/ExerciseDetails.gql | 30 +- .../backend/queries/ExerciseParameters.gql | 30 +- .../src/backend/queries/ExercisesList.gql | 28 +- .../src/backend/queries/GenreDetails.gql | 28 +- .../src/backend/queries/GenresList.gql | 22 +- .../src/backend/queries/ImportReports.gql | 36 +- .../src/backend/queries/LatestUserSummary.gql | 67 +- .../src/backend/queries/MetadataDetails.gql | 208 +- .../backend/queries/MetadataGroupDetails.gql | 28 +- .../backend/queries/MetadataGroupSearch.gql | 24 +- .../src/backend/queries/MetadataList.gql | 14 +- .../src/backend/queries/MetadataSearch.gql | 32 +- .../src/backend/queries/PeopleSearch.gql | 24 +- .../src/backend/queries/PersonDetails.gql | 50 +- .../src/backend/queries/UserDetails.gql | 18 +- .../backend/queries/UserExerciseDetails.gql | 88 +- .../backend/queries/UserMeasurementsList.gql | 62 +- .../backend/queries/UserMetadataDetails.gql | 74 +- .../queries/UserMetadataGroupDetails.gql | 16 +- .../src/backend/queries/UserPersonDetails.gql | 16 +- .../src/backend/queries/UserPreferences.gql | 184 +- .../backend/queries/UserWorkoutDetails.gql | 40 +- .../queries/UserWorkoutTemplateDetails.gql | 34 +- .../queries/UserWorkoutTemplatesList.gql | 30 +- .../src/backend/queries/UserWorkoutsList.gql | 32 +- libs/graphql/src/backend/queries/combined.gql | 254 +- .../graphql/src/backend/queries/fragments.gql | 298 +- libs/transactional/package.json | 5 + libs/ts-utils/package.json | 7 +- libs/ts-utils/src/index.ts | 8 + package.json | 4 +- yarn.lock | 2735 ++++++++--------- 133 files changed, 3682 insertions(+), 3716 deletions(-) create mode 100644 crates/migrations/src/m20241019_changes_for_issue_964.rs create mode 100644 crates/services/integration/src/push/jellyfin.rs create mode 100644 crates/utils/external/Cargo.toml create mode 100644 crates/utils/external/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 1a8029d590..487f7a7d3e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -909,6 +909,7 @@ dependencies = [ "apalis", "chrono", "chrono-tz", + "database-models", "enums", "fitness-models", "media-models", @@ -1708,7 +1709,6 @@ dependencies = [ name = "database-utils" version = "0.1.0" dependencies = [ - "apalis", "application-utils", "async-graphql", "background", @@ -1757,7 +1757,6 @@ name = "dependent-utils" version = "0.1.0" dependencies = [ "anyhow", - "apalis", "application-utils", "async-graphql", "background", @@ -2259,7 +2258,6 @@ dependencies = [ name = "exporter-service" version = "0.1.0" dependencies = [ - "apalis", "async-graphql", "background", "chrono", @@ -2281,6 +2279,19 @@ dependencies = [ "tokio-util", ] +[[package]] +name = "external-utils" +version = "0.1.0" +dependencies = [ + "anyhow", + "common-utils", + "reqwest 0.12.8", + "sea-orm", + "serde", + "serde_json", + "tracing", +] + [[package]] name = "fast_chemail" version = "0.9.6" @@ -2380,7 +2391,6 @@ dependencies = [ name = "fitness-service" version = "0.1.0" dependencies = [ - "apalis", "application-utils", "async-graphql", "background", @@ -3338,7 +3348,6 @@ name = "importer-service" version = "0.1.0" dependencies = [ "anyhow", - "apalis", "application-utils", "async-graphql", "background", @@ -3355,6 +3364,7 @@ dependencies = [ "enum_meta", "enums", "env-utils", + "external-utils", "fitness-models", "flate2", "importer-models", @@ -3431,6 +3441,7 @@ dependencies = [ "dependent-utils", "enums", "eventsource-stream", + "external-utils", "itertools 0.13.0", "media-models", "providers", @@ -3843,7 +3854,6 @@ dependencies = [ name = "miscellaneous-service" version = "0.1.0" dependencies = [ - "apalis", "application-utils", "async-graphql", "background", @@ -6319,6 +6329,7 @@ name = "supporting-service" version = "0.1.0" dependencies = [ "apalis", + "async-graphql", "background", "cache-service", "chrono-tz", diff --git a/Cargo.toml b/Cargo.toml index aa4d15ba9d..15aa37cba9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,6 +41,7 @@ members = [ "crates/utils/common", "crates/utils/database", "crates/utils/dependent", + "crates/utils/external", "crates/utils/env", ] resolver = "2" diff --git a/apps/backend/src/job.rs b/apps/backend/src/job.rs index d93dcba35c..194f2bedf1 100644 --- a/apps/backend/src/job.rs +++ b/apps/backend/src/job.rs @@ -96,6 +96,10 @@ pub async fn perform_application_job( .update_person_and_notify_users(person_id) .await .is_ok(), + ApplicationJob::HandleAfterMediaSeenTasks(seen) => misc_service + .handle_after_media_seen_tasks(seen) + .await + .is_ok(), ApplicationJob::UpdateMetadataGroup(metadata_group_id) => misc_service .update_metadata_group(&metadata_group_id) .await @@ -135,6 +139,10 @@ pub async fn perform_application_job( .await .is_ok() } + ApplicationJob::HandleOnSeenComplete(id) => integration_service + .handle_on_seen_complete(id) + .await + .is_ok(), }; ryot_log!( trace, diff --git a/apps/frontend/app/lib/utilities.server.ts b/apps/frontend/app/lib/utilities.server.ts index 136309c4ab..6b44bf03ab 100644 --- a/apps/frontend/app/lib/utilities.server.ts +++ b/apps/frontend/app/lib/utilities.server.ts @@ -17,7 +17,7 @@ import { } from "@ryot/generated/graphql/backend/graphql"; import { UserDetailsDocument } from "@ryot/generated/graphql/backend/graphql"; import { isEmpty } from "@ryot/ts-utils"; -import { type CookieSerializeOptions, parse, serialize } from "cookie"; +import { type SerializeOptions, parse, serialize } from "cookie"; import { ClientError, GraphQLClient, @@ -176,7 +176,7 @@ export const getCachedCoreDetails = async () => { export const getCachedUserDetails = async (request: Request) => { const token = getAuthorizationCookie(request); return await queryClient.ensureQueryData({ - queryKey: queryFactory.users.details(token).queryKey, + queryKey: queryFactory.users.details(token ?? "").queryKey, queryFn: () => serverGqlService.authenticatedRequest( request, @@ -366,7 +366,7 @@ export const getCookiesForApplication = async ( const [{ coreDetails }] = await Promise.all([getCachedCoreDetails()]); const maxAge = (tokenValidForDays || coreDetails.tokenValidForDays) * 24 * 60 * 60; - const options = { maxAge, path: "/" } satisfies CookieSerializeOptions; + const options = { maxAge, path: "/" } satisfies SerializeOptions; return combineHeaders({ "set-cookie": serialize(AUTH_COOKIE_NAME, token, options), }); @@ -391,9 +391,12 @@ export const getWorkoutCookieValue = (request: Request) => { }; export const isWorkoutActive = (request: Request) => { - const inProgress = [FitnessAction.LogWorkout, FitnessAction.UpdateWorkout] - .map(String) - .includes(getWorkoutCookieValue(request)); + const cookieValue = getWorkoutCookieValue(request); + const inProgress = + cookieValue && + [FitnessAction.LogWorkout, FitnessAction.UpdateWorkout] + .map(String) + .includes(cookieValue); return inProgress; }; diff --git a/apps/frontend/app/root.tsx b/apps/frontend/app/root.tsx index 72f7ed912b..88b8965aed 100644 --- a/apps/frontend/app/root.tsx +++ b/apps/frontend/app/root.tsx @@ -12,9 +12,9 @@ import "@mantine/core/styles.css"; import "@mantine/notifications/styles.css"; import { type LinksFunction, + type LoaderFunctionArgs, type MetaFunction, - unstable_data, - unstable_defineLoader, + data, } from "@remix-run/node"; import { Links, @@ -93,7 +93,7 @@ export const links: LinksFunction = () => { ]; }; -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const { toast, headers: toastHeaders } = await getToast(request); const colorScheme = await colorSchemeCookie.parse( request.headers.get("cookie") || "", @@ -114,8 +114,8 @@ export const loader = unstable_defineLoader(async ({ request }) => { } } - return unstable_data({ toast, defaultColorScheme, isIOS18 }, { headers }); -}); + return data({ toast, defaultColorScheme, isIOS18 }, { headers }); +}; const DefaultHeadTags = () => { const loaderData = useLoaderData(); diff --git a/apps/frontend/app/routes/_dashboard._index.tsx b/apps/frontend/app/routes/_dashboard._index.tsx index a505f966c4..bbaba20db5 100644 --- a/apps/frontend/app/routes/_dashboard._index.tsx +++ b/apps/frontend/app/routes/_dashboard._index.tsx @@ -17,8 +17,7 @@ import { useMantineTheme, } from "@mantine/core"; import { useInViewport } from "@mantine/hooks"; -import { unstable_defineLoader } from "@remix-run/node"; -import type { MetaArgs_SingleFetch } from "@remix-run/react"; +import type { LoaderFunctionArgs, MetaArgs } from "@remix-run/node"; import { Link, useLoaderData } from "@remix-run/react"; import { type CalendarEventPartFragment, @@ -89,7 +88,7 @@ const getTake = (preferences: UserPreferences, el: DashboardElementLot) => { return t; }; -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const preferences = await getCachedUserPreferences(request); const takeUpcoming = getTake(preferences, DashboardElementLot.Upcoming); const takeInProgress = getTake(preferences, DashboardElementLot.InProgress); @@ -143,9 +142,9 @@ export const loader = unstable_defineLoader(async ({ request }) => { inProgressCollectionContents, userRecommendations, }; -}); +}; -export const meta = (_args: MetaArgs_SingleFetch) => { +export const meta = (_args: MetaArgs) => { return [{ title: "Home | Ryot" }]; }; @@ -282,6 +281,12 @@ export default function Page() { value: latestUserSummary.videoGameCount, type: "number", }, + { + label: "Runtime", + value: latestUserSummary.totalVideoGameDuration, + type: "duration", + hideIfZero: true, + }, ]} /> ; -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const cookieName = await getEnhancedCookieName("calendar", request); await redirectUsingEnhancedCookieSearchParams(request, cookieName); const query = zx.parseQuery(request, searchParamsSchema); @@ -51,9 +47,9 @@ export const loader = unstable_defineLoader(async ({ request }) => { }), ]); return { query, userCalendarEvents, cookieName }; -}); +}; -export const meta = (_args: MetaArgs_SingleFetch) => { +export const meta = (_args: MetaArgs) => { return [{ title: "Calendar | Ryot" }]; }; diff --git a/apps/frontend/app/routes/_dashboard.collections.$id._index.tsx b/apps/frontend/app/routes/_dashboard.collections.$id._index.tsx index 258388564b..ea69460ba5 100644 --- a/apps/frontend/app/routes/_dashboard.collections.$id._index.tsx +++ b/apps/frontend/app/routes/_dashboard.collections.$id._index.tsx @@ -15,12 +15,8 @@ import { Title, } from "@mantine/core"; import { useDisclosure } from "@mantine/hooks"; -import { unstable_defineLoader } from "@remix-run/node"; -import { - type MetaArgs_SingleFetch, - useLoaderData, - useNavigate, -} from "@remix-run/react"; +import type { LoaderFunctionArgs, MetaArgs } from "@remix-run/node"; +import { useLoaderData, useNavigate } from "@remix-run/react"; import { CollectionContentsDocument, CollectionContentsSortBy, @@ -81,7 +77,7 @@ const searchParamsSchema = z.object({ export type SearchParams = z.infer; -export const loader = unstable_defineLoader(async ({ request, params }) => { +export const loader = async ({ request, params }: LoaderFunctionArgs) => { const { id: collectionId } = zx.parseParams(params, { id: z.string() }); const cookieName = await getEnhancedCookieName( `collections.details.${collectionId}`, @@ -108,9 +104,9 @@ export const loader = unstable_defineLoader(async ({ request, params }) => { query[pageQueryParam] || 1, ); return { collectionId, query, collectionContents, cookieName, totalPages }; -}); +}; -export const meta = ({ data }: MetaArgs_SingleFetch) => { +export const meta = ({ data }: MetaArgs) => { return [{ title: `${data?.collectionContents.details.name} | Ryot` }]; }; diff --git a/apps/frontend/app/routes/_dashboard.collections.list.tsx b/apps/frontend/app/routes/_dashboard.collections.list.tsx index 5d8a086e6e..326c32ed50 100644 --- a/apps/frontend/app/routes/_dashboard.collections.list.tsx +++ b/apps/frontend/app/routes/_dashboard.collections.list.tsx @@ -23,11 +23,14 @@ import { } from "@mantine/core"; import { useDidUpdate, useHover, useListState } from "@mantine/hooks"; import { notifications } from "@mantine/notifications"; -import { unstable_defineAction, unstable_defineLoader } from "@remix-run/node"; +import type { + ActionFunctionArgs, + LoaderFunctionArgs, + MetaArgs, +} from "@remix-run/node"; import { Form, Link, - type MetaArgs_SingleFetch, useLoaderData, useNavigation, useSearchParams, @@ -46,6 +49,7 @@ import { } from "@ryot/generated/graphql/backend/graphql"; import { changeCase, + getActionIntent, isString, processSubmission, truncate, @@ -61,7 +65,7 @@ import { ClientError } from "graphql-request"; import { useEffect, useState } from "react"; import { Virtuoso } from "react-virtuoso"; import { $path } from "remix-routes"; -import { namedAction } from "remix-utils/named-action"; +import { match } from "ts-pattern"; import { withQuery } from "ufo"; import { z } from "zod"; import { zx } from "zodix"; @@ -91,24 +95,25 @@ import { serverGqlService, } from "~/lib/utilities.server"; -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const cookieName = await getEnhancedCookieName("collections.list", request); await redirectUsingEnhancedCookieSearchParams(request, cookieName); const [{ usersList }] = await Promise.all([ serverGqlService.authenticatedRequest(request, UsersListDocument, {}), ]); return { usersList, cookieName }; -}); +}; -export const meta = (_args: MetaArgs_SingleFetch) => { +export const meta = (_args: MetaArgs) => { return [{ title: "Your collections | Ryot" }]; }; -export const action = unstable_defineAction(async ({ request }) => { +export const action = async ({ request }: ActionFunctionArgs) => { const formData = await request.clone().formData(); await removeCachedUserCollectionsList(request); - return namedAction(request, { - createOrUpdate: async () => { + const intent = getActionIntent(request); + return await match(intent) + .with("createOrUpdate", async () => { const submission = processSubmission(formData, createOrUpdateSchema); try { await serverGqlService.authenticatedRequest( @@ -141,8 +146,8 @@ export const action = unstable_defineAction(async ({ request }) => { }, ); } - }, - delete: async () => { + }) + .with("delete", async () => { const submission = processSubmission( formData, z.object({ collectionName: z.string() }), @@ -168,9 +173,9 @@ export const action = unstable_defineAction(async ({ request }) => { }), }, ); - }, - }); -}); + }) + .run(); +}; const createOrUpdateSchema = z.object({ name: z.string(), diff --git a/apps/frontend/app/routes/_dashboard.fitness.$action.tsx b/apps/frontend/app/routes/_dashboard.fitness.$action.tsx index 84d812e8c3..4cf92f4248 100644 --- a/apps/frontend/app/routes/_dashboard.fitness.$action.tsx +++ b/apps/frontend/app/routes/_dashboard.fitness.$action.tsx @@ -42,15 +42,13 @@ import { useToggle, } from "@mantine/hooks"; import { notifications } from "@mantine/notifications"; -import { unstable_defineAction, unstable_defineLoader } from "@remix-run/node"; +import type { LoaderFunctionArgs, MetaArgs } from "@remix-run/node"; import { Link, - useFetcher, useLoaderData, useNavigate, useRevalidator, } from "@remix-run/react"; -import type { MetaArgs_SingleFetch } from "@remix-run/react"; import { CreateOrUpdateUserWorkoutDocument, CreateOrUpdateUserWorkoutTemplateDocument, @@ -98,10 +96,8 @@ import { useEffect, useMemo, useRef, useState } from "react"; import Webcam from "react-webcam"; import { $path } from "remix-routes"; import { ClientOnly } from "remix-utils/client-only"; -import { namedAction } from "remix-utils/named-action"; import invariant from "tiny-invariant"; import { match } from "ts-pattern"; -import { withQuery } from "ufo"; import { useInterval, useOnClickOutside } from "usehooks-ts"; import { v4 as randomUUID } from "uuid"; import { z } from "zod"; @@ -117,6 +113,7 @@ import { FitnessAction, FitnessEntity, PRO_REQUIRED_MESSAGE, + clientGqlService, dayjsLib, getSetColor, getSurroundingElements, @@ -149,15 +146,11 @@ import { useMeasurementsDrawerOpen, useTimerAtom, } from "~/lib/state/fitness"; -import { - isWorkoutActive, - redirectWithToast, - serverGqlService, -} from "~/lib/utilities.server"; +import { isWorkoutActive, redirectWithToast } from "~/lib/utilities.server"; const workoutCookieName = CurrentWorkoutKey; -export const loader = unstable_defineLoader(async ({ params, request }) => { +export const loader = async ({ params, request }: LoaderFunctionArgs) => { const { action } = zx.parseParams(params, { action: z.nativeEnum(FitnessAction), }); @@ -177,49 +170,12 @@ export const loader = unstable_defineLoader(async ({ params, request }) => { isUpdatingWorkout: action === FitnessAction.UpdateWorkout, isCreatingTemplate: action === FitnessAction.CreateTemplate, }; -}); +}; -export const meta = ({ data }: MetaArgs_SingleFetch) => { +export const meta = ({ data }: MetaArgs) => { return [{ title: `${changeCase(data?.action || "")} | Ryot` }]; }; -export const action = unstable_defineAction(async ({ request }) => { - const formData = await request.clone().formData(); - const workout = JSON.parse(formData.get("workout") as string); - return namedAction(request, { - createWorkout: async () => { - const { createOrUpdateUserWorkout } = - await serverGqlService.authenticatedRequest( - request, - CreateOrUpdateUserWorkoutDocument, - workout, - ); - return redirectWithToast( - $path("/fitness/:entity/:id", { - entity: "workouts", - id: createOrUpdateUserWorkout, - }), - { message: "Workout completed successfully", type: "success" }, - ); - }, - createTemplate: async () => { - const { createOrUpdateUserWorkoutTemplate } = - await serverGqlService.authenticatedRequest( - request, - CreateOrUpdateUserWorkoutTemplateDocument, - workout, - ); - return redirectWithToast( - $path("/fitness/:entity/:id", { - entity: "templates", - id: createOrUpdateUserWorkoutTemplate, - }), - { message: "Template created successfully", type: "success" }, - ); - }, - }); -}); - const deleteUploadedAsset = (key: string) => { const formData = new FormData(); formData.append("key", key); @@ -319,8 +275,6 @@ export default function Page() { setCurrentTimer(RESET); }; - const createUserWorkoutFetcher = useFetcher(); - return ( {currentWorkout ? ( @@ -492,21 +446,45 @@ export default function Page() { }); } stopTimer(); - if (!loaderData.isCreatingTemplate) { + const [entityId, fitnessEntity] = await match( + loaderData.isCreatingTemplate, + ) + .with(true, () => + clientGqlService + .request( + CreateOrUpdateUserWorkoutTemplateDocument, + input, + ) + .then((c) => [ + c.createOrUpdateUserWorkoutTemplate, + FitnessEntity.Templates, + ]), + ) + .with(false, () => + clientGqlService + .request( + CreateOrUpdateUserWorkoutDocument, + input, + ) + .then((c) => [ + c.createOrUpdateUserWorkout, + FitnessEntity.Workouts, + ]), + ) + .exhaustive(); + notifications.show({ + color: "green", + message: "Saved successfully", + }); + Cookies.remove(workoutCookieName); + revalidator.revalidate(); + if (loaderData.action === FitnessAction.LogWorkout) events.createWorkout(); - Cookies.remove(workoutCookieName); - } - createUserWorkoutFetcher.submit( - { workout: JSON.stringify(input) }, - { - method: "post", - action: withQuery(".", { - intent: loaderData.isCreatingTemplate - ? "createTemplate" - : "createWorkout", - }), - encType: "multipart/form-data", - }, + navigate( + $path("/fitness/:entity/:id", { + entity: fitnessEntity, + id: entityId, + }), ); } }} @@ -1171,7 +1149,7 @@ const ExerciseDisplay = (props: { leftSection={} onClick={() => props.openSupersetModal(exercise.identifier)} > - Superset + {partOfSuperset ? "Edit" : "Create"} superset } @@ -1239,6 +1217,19 @@ const ExerciseDisplay = (props: { for (const asset of assets) deleteUploadedAsset(asset.key); setCurrentWorkout( produce(currentWorkout, (draft) => { + const idx = draft.supersets.findIndex((s) => + s.exercises.includes(exercise.identifier), + ); + if (idx !== -1) { + if (draft.supersets[idx].exercises.length === 2) + draft.supersets.splice(idx, 1); + else + draft.supersets[idx].exercises = draft.supersets[ + idx + ].exercises.filter( + (e) => e !== exercise.identifier, + ); + } draft.exercises.splice(props.exerciseIdx, 1); }), ); diff --git a/apps/frontend/app/routes/_dashboard.fitness.$entity.$id._index.tsx b/apps/frontend/app/routes/_dashboard.fitness.$entity.$id._index.tsx index e7494c1f32..a28c634655 100644 --- a/apps/frontend/app/routes/_dashboard.fitness.$entity.$id._index.tsx +++ b/apps/frontend/app/routes/_dashboard.fitness.$entity.$id._index.tsx @@ -17,8 +17,11 @@ import { $path } from "remix-routes"; import "@mantine/dates/styles.css"; import { useDisclosure } from "@mantine/hooks"; import { notifications } from "@mantine/notifications"; -import { unstable_defineAction, unstable_defineLoader } from "@remix-run/node"; -import type { MetaArgs_SingleFetch } from "@remix-run/react"; +import type { + ActionFunctionArgs, + LoaderFunctionArgs, + MetaArgs, +} from "@remix-run/node"; import { Form, Link, useLoaderData } from "@remix-run/react"; import { DeleteUserWorkoutDocument, @@ -30,6 +33,7 @@ import { } from "@ryot/generated/graphql/backend/graphql"; import { changeCase, + getActionIntent, humanizeDuration, processSubmission, } from "@ryot/ts-utils"; @@ -50,7 +54,6 @@ import { IconZzz, } from "@tabler/icons-react"; import { type ReactNode, useState } from "react"; -import { namedAction } from "remix-utils/named-action"; import { match } from "ts-pattern"; import { withQuery } from "ufo"; import { z } from "zod"; @@ -82,7 +85,7 @@ import { serverGqlService, } from "~/lib/utilities.server"; -export const loader = unstable_defineLoader(async ({ request, params }) => { +export const loader = async ({ request, params }: LoaderFunctionArgs) => { const { id: entityId, entity } = zx.parseParams(params, { id: z.string(), entity: z.nativeEnum(FitnessEntity), @@ -156,16 +159,17 @@ export const loader = unstable_defineLoader(async ({ request, params }) => { }) .exhaustive(); return { entityId, entity, ...resp }; -}); +}; -export const meta = ({ data }: MetaArgs_SingleFetch) => { +export const meta = ({ data }: MetaArgs) => { return [{ title: `${data?.entityName} | Ryot` }]; }; -export const action = unstable_defineAction(async ({ request }) => { +export const action = async ({ request }: ActionFunctionArgs) => { const formData = await request.clone().formData(); - return namedAction(request, { - edit: async () => { + const intent = getActionIntent(request); + return await match(intent) + .with("edit", async () => { const submission = processSubmission(formData, editWorkoutSchema); await serverGqlService.authenticatedRequest( request, @@ -178,8 +182,8 @@ export const action = unstable_defineAction(async ({ request }) => { message: "Workout edited successfully", }), }); - }, - delete: async () => { + }) + .with("delete", async () => { const submission = processSubmission(formData, deleteSchema); if (submission.workoutId) await serverGqlService.authenticatedRequest( @@ -198,9 +202,9 @@ export const action = unstable_defineAction(async ({ request }) => { type: "success", message: `${changeCase(entity)} deleted successfully`, }); - }, - }); -}); + }) + .run(); +}; const deleteSchema = z.object({ workoutId: z.string().optional(), diff --git a/apps/frontend/app/routes/_dashboard.fitness.$entity.list.tsx b/apps/frontend/app/routes/_dashboard.fitness.$entity.list.tsx index e5f3ab0af1..68177e1b24 100644 --- a/apps/frontend/app/routes/_dashboard.fitness.$entity.list.tsx +++ b/apps/frontend/app/routes/_dashboard.fitness.$entity.list.tsx @@ -13,12 +13,8 @@ import { Title, } from "@mantine/core"; import { notifications } from "@mantine/notifications"; -import { unstable_defineLoader } from "@remix-run/node"; -import { - Link, - type MetaArgs_SingleFetch, - useLoaderData, -} from "@remix-run/react"; +import type { LoaderFunctionArgs, MetaArgs } from "@remix-run/node"; +import { Link, useLoaderData } from "@remix-run/react"; import { UserWorkoutTemplatesListDocument, UserWorkoutsListDocument, @@ -72,7 +68,7 @@ const searchParamsSchema = z.object({ export type SearchParams = z.infer; -export const loader = unstable_defineLoader(async ({ params, request }) => { +export const loader = async ({ params, request }: LoaderFunctionArgs) => { const { entity } = zx.parseParams(params, { entity: z.nativeEnum(FitnessEntity), }); @@ -128,9 +124,9 @@ export const loader = unstable_defineLoader(async ({ params, request }) => { query[pageQueryParam], ); return { query, entity, itemList, cookieName, totalPages }; -}); +}; -export const meta = ({ data }: MetaArgs_SingleFetch) => { +export const meta = ({ data }: MetaArgs) => { return [{ title: `${changeCase(data?.entity || "")} | Ryot` }]; }; diff --git a/apps/frontend/app/routes/_dashboard.fitness.exercises.$action.tsx b/apps/frontend/app/routes/_dashboard.fitness.exercises.$action.tsx index 38c48335fb..c46982874c 100644 --- a/apps/frontend/app/routes/_dashboard.fitness.exercises.$action.tsx +++ b/apps/frontend/app/routes/_dashboard.fitness.exercises.$action.tsx @@ -11,16 +11,14 @@ import { Title, } from "@mantine/core"; import { + type ActionFunctionArgs, + type LoaderFunctionArgs, + type MetaArgs, + data, redirect, - unstable_defineAction, - unstable_defineLoader, unstable_parseMultipartFormData, } from "@remix-run/node"; -import { - Form, - type MetaArgs_SingleFetch, - useLoaderData, -} from "@remix-run/react"; +import { Form, useLoaderData } from "@remix-run/react"; import { CreateCustomExerciseDocument, ExerciseDetailsDocument, @@ -32,11 +30,15 @@ import { ExerciseMuscle, UpdateCustomExerciseDocument, } from "@ryot/generated/graphql/backend/graphql"; -import { cloneDeep, processSubmission, startCase } from "@ryot/ts-utils"; +import { + cloneDeep, + getActionIntent, + processSubmission, + startCase, +} from "@ryot/ts-utils"; import { IconPhoto } from "@tabler/icons-react"; import { ClientError } from "graphql-request"; import { $path } from "remix-routes"; -import { namedAction } from "remix-utils/named-action"; import invariant from "tiny-invariant"; import { match } from "ts-pattern"; import { withQuery } from "ufo"; @@ -58,7 +60,7 @@ enum Action { Update = "update", } -export const loader = unstable_defineLoader(async ({ params, request }) => { +export const loader = async ({ params, request }: LoaderFunctionArgs) => { const { action } = zx.parseParams(params, { action: z.nativeEnum(Action) }); const query = zx.parseQuery(request, searchParamsSchema); const details = await match(action) @@ -73,21 +75,18 @@ export const loader = unstable_defineLoader(async ({ params, request }) => { return exerciseDetails; }) .exhaustive(); - return { - action, - details, - }; -}); + return { action, details }; +}; -export const meta = (_args: MetaArgs_SingleFetch) => { +export const meta = (_args: MetaArgs) => { return [{ title: "Create Exercise | Ryot" }]; }; -export const action = unstable_defineAction(async ({ request }) => { - const uploaders = s3FileUploader("exercises"); +export const action = async ({ request }: ActionFunctionArgs) => { + const uploader = s3FileUploader("exercises"); const formData = await unstable_parseMultipartFormData( request.clone(), - uploaders, + uploader, ); const submission = processSubmission(formData, schema); const muscles = submission.muscles @@ -107,8 +106,9 @@ export const action = unstable_defineAction(async ({ request }) => { }, }; try { - return await namedAction(request, { - [Action.Create]: async () => { + const intent = getActionIntent(request); + return await match(intent) + .with(Action.Create, async () => { const { createCustomExercise } = await serverGqlService.authenticatedRequest( request, @@ -120,8 +120,8 @@ export const action = unstable_defineAction(async ({ request }) => { id: encodeURIComponent(createCustomExercise), }), ); - }, - [Action.Update]: async () => { + }) + .with(Action.Update, async () => { invariant(submission.oldName); await serverGqlService.authenticatedRequest( request, @@ -129,12 +129,12 @@ export const action = unstable_defineAction(async ({ request }) => { { input: { ...input, oldName: submission.oldName } }, ); return redirect($path("/fitness/exercises/list")); - }, - }); + }) + .run(); } catch (e) { if (e instanceof ClientError && e.response.errors) { const message = e.response.errors[0].message; - return Response.json( + return data( { error: e.message }, { status: 400, @@ -144,7 +144,7 @@ export const action = unstable_defineAction(async ({ request }) => { } throw e; } -}); +}; const optionalString = z.string().optional(); const optionalStringArray = z.array(z.string()).optional(); 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 ea8c204844..d409c45935 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 @@ -24,8 +24,11 @@ import { rem, } from "@mantine/core"; import { useDisclosure } from "@mantine/hooks"; -import { unstable_defineAction, unstable_defineLoader } from "@remix-run/node"; -import type { MetaArgs_SingleFetch } from "@remix-run/react"; +import type { + ActionFunctionArgs, + LoaderFunctionArgs, + MetaArgs, +} from "@remix-run/node"; import { Form, Link, useLoaderData, useNavigate } from "@remix-run/react"; import { EntityLot, @@ -104,7 +107,7 @@ export type SearchParams = z.infer; const paramsSchema = { id: z.string() }; -export const loader = unstable_defineLoader(async ({ params, request }) => { +export const loader = async ({ params, request }: LoaderFunctionArgs) => { const { id: exerciseId } = zx.parseParams(params, paramsSchema); const query = zx.parseQuery(request, searchParamsSchema); const workoutInProgress = !!getWorkoutCookieValue(request); @@ -126,13 +129,13 @@ export const loader = unstable_defineLoader(async ({ params, request }) => { exerciseParameters, userExerciseDetails, }; -}); +}; -export const meta = ({ data }: MetaArgs_SingleFetch) => { +export const meta = ({ data }: MetaArgs) => { return [{ title: `${data?.exerciseDetails.id} | Ryot` }]; }; -export const action = unstable_defineAction(async ({ params, request }) => { +export const action = async ({ params, request }: ActionFunctionArgs) => { const { id: exerciseId } = zx.parseParams(params, paramsSchema); const entries = Object.entries(Object.fromEntries(await request.formData())); const submission = []; @@ -156,7 +159,7 @@ export const action = unstable_defineAction(async ({ params, request }) => { message: "Preferences updated", }), }); -}); +}; export default function Page() { const loaderData = useLoaderData(); diff --git a/apps/frontend/app/routes/_dashboard.fitness.exercises.list.tsx b/apps/frontend/app/routes/_dashboard.fitness.exercises.list.tsx index 2b19203954..2005456694 100644 --- a/apps/frontend/app/routes/_dashboard.fitness.exercises.list.tsx +++ b/apps/frontend/app/routes/_dashboard.fitness.exercises.list.tsx @@ -21,13 +21,8 @@ import { rem, } from "@mantine/core"; import { useDisclosure, useListState } from "@mantine/hooks"; -import { unstable_defineLoader } from "@remix-run/node"; -import { - Link, - type MetaArgs_SingleFetch, - useLoaderData, - useNavigate, -} from "@remix-run/react"; +import type { LoaderFunctionArgs, MetaArgs } from "@remix-run/node"; +import { Link, useLoaderData, useNavigate } from "@remix-run/react"; import { ExerciseEquipment, ExerciseForce, @@ -92,7 +87,7 @@ const searchParamsSchema = z.object({ export type SearchParams = z.infer; -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const cookieName = await getEnhancedCookieName("exercises.list", request); await redirectUsingEnhancedCookieSearchParams(request, cookieName); const query = zx.parseQuery(request, searchParamsSchema); @@ -134,9 +129,9 @@ export const loader = unstable_defineLoader(async ({ request }) => { workoutInProgress, exerciseParameters, }; -}); +}; -export const meta = (_args: MetaArgs_SingleFetch) => { +export const meta = (_args: MetaArgs) => { return [{ title: "Exercises | Ryot" }]; }; diff --git a/apps/frontend/app/routes/_dashboard.fitness.measurements.list.tsx b/apps/frontend/app/routes/_dashboard.fitness.measurements.list.tsx index 88bf336438..61b2360f7d 100644 --- a/apps/frontend/app/routes/_dashboard.fitness.measurements.list.tsx +++ b/apps/frontend/app/routes/_dashboard.fitness.measurements.list.tsx @@ -12,17 +12,17 @@ import { Text, Title, } from "@mantine/core"; -import { unstable_defineAction, unstable_defineLoader } from "@remix-run/node"; -import { - Form, - type MetaArgs_SingleFetch, - useLoaderData, -} from "@remix-run/react"; +import type { + ActionFunctionArgs, + LoaderFunctionArgs, + MetaArgs, +} from "@remix-run/node"; +import { Form, useLoaderData } from "@remix-run/react"; import { DeleteUserMeasurementDocument, UserMeasurementsListDocument, } from "@ryot/generated/graphql/backend/graphql"; -import { processSubmission, startCase } from "@ryot/ts-utils"; +import { getActionIntent, processSubmission, startCase } from "@ryot/ts-utils"; import { IconChartArea, IconPlus, @@ -30,7 +30,8 @@ import { IconTrash, } from "@tabler/icons-react"; import { DataTable } from "mantine-datatable"; -import { namedAction } from "remix-utils/named-action"; +import { match } from "ts-pattern"; +import { withQuery } from "ufo"; import { useLocalStorage } from "usehooks-ts"; import { z } from "zod"; import { zx } from "zodix"; @@ -63,7 +64,7 @@ export type SearchParams = z.infer; const defaultTimeSpan = TimeSpan.Last30Days; -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const cookieName = await getEnhancedCookieName("measurements.list", request); await redirectUsingEnhancedCookieSearchParams(request, cookieName); const query = zx.parseQuery(request, searchParamsSchema); @@ -82,16 +83,17 @@ export const loader = unstable_defineLoader(async ({ request }) => { ), ]); return { query, userMeasurementsList, cookieName }; -}); +}; -export const meta = (_args: MetaArgs_SingleFetch) => { +export const meta = (_args: MetaArgs) => { return [{ title: "Measurements | Ryot" }]; }; -export const action = unstable_defineAction(async ({ request }) => { +export const action = async ({ request }: ActionFunctionArgs) => { const formData = await request.clone().formData(); - return namedAction(request, { - delete: async () => { + const intent = getActionIntent(request); + return await match(intent) + .with("delete", async () => { const submission = processSubmission(formData, deleteSchema); await serverGqlService.authenticatedRequest( request, @@ -104,9 +106,9 @@ export const action = unstable_defineAction(async ({ request }) => { message: "Measurement deleted successfully", }), }); - }, - }); -}); + }) + .run(); +}; const deleteSchema = z.object({ timestamp: z.string() }); @@ -220,8 +222,8 @@ export default function Page() { records={loaderData.userMeasurementsList} columns={[ { - accessor: "timestamp", width: 200, + accessor: "timestamp", render: ({ timestamp }) => dayjsLib(timestamp).format("lll"), }, ...([ @@ -247,16 +249,14 @@ export default function Page() { // biome-ignore lint/suspicious/noExplicitAny: required here })) as any), { - accessor: "Delete", width: 80, + accessor: "Delete", textAlign: "center", render: ({ timestamp }) => ( -
- + { +export const loader = async ({ request, params }: LoaderFunctionArgs) => { const { action, lot } = zx.parseParams(params, { action: z.nativeEnum(Action), lot: z.string().transform((v) => getLot(v) as MediaLot), @@ -218,9 +217,9 @@ export const loader = unstable_defineLoader(async ({ request, params }) => { url: withoutHost(url.href), [pageQueryParam]: Number(query[pageQueryParam]), }; -}); +}; -export const meta = ({ params }: MetaArgs_SingleFetch) => { +export const meta = ({ params }: MetaArgs) => { return [ { title: `${changeCase(params.action || "")} ${changeCase( diff --git a/apps/frontend/app/routes/_dashboard.media.create.tsx b/apps/frontend/app/routes/_dashboard.media.create.tsx index 16083cf9d9..0a55245a9f 100644 --- a/apps/frontend/app/routes/_dashboard.media.create.tsx +++ b/apps/frontend/app/routes/_dashboard.media.create.tsx @@ -15,12 +15,12 @@ import { Title, } from "@mantine/core"; import { + type ActionFunctionArgs, + type LoaderFunctionArgs, + type MetaArgs, redirect, - unstable_defineAction, - unstable_defineLoader, unstable_parseMultipartFormData, } from "@remix-run/node"; -import type { MetaArgs_SingleFetch } from "@remix-run/react"; import { Form, useLoaderData } from "@remix-run/react"; import { CreateCustomMetadataDocument, @@ -40,16 +40,16 @@ const searchParamsSchema = z.object({ export type SearchParams = z.infer; -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const query = zx.parseQuery(request, searchParamsSchema); return { query }; -}); +}; -export const meta = (_args: MetaArgs_SingleFetch) => { +export const meta = (_args: MetaArgs) => { return [{ title: "Create Media | Ryot" }]; }; -export const action = unstable_defineAction(async ({ request }) => { +export const action = async ({ request }: ActionFunctionArgs) => { const uploaders = s3FileUploader("metadata"); const formData = await unstable_parseMultipartFormData(request, uploaders); const submission = processSubmission(formData, schema); @@ -69,7 +69,7 @@ export const action = unstable_defineAction(async ({ request }) => { { input }, ); return redirect($path("/media/item/:id", { id: createCustomMetadata.id })); -}); +}; const optionalString = z.string().optional(); const optionalStringArray = z.array(z.string()).optional(); 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 7a66f3ccc7..975d400f10 100644 --- a/apps/frontend/app/routes/_dashboard.media.genre.$id._index.tsx +++ b/apps/frontend/app/routes/_dashboard.media.genre.$id._index.tsx @@ -7,8 +7,7 @@ import { Text, Title, } from "@mantine/core"; -import { unstable_defineLoader } from "@remix-run/node"; -import type { MetaArgs_SingleFetch } from "@remix-run/react"; +import type { LoaderFunctionArgs, MetaArgs } from "@remix-run/node"; import { useLoaderData } from "@remix-run/react"; import { GenreDetailsDocument } from "@ryot/generated/graphql/backend/graphql"; import { z } from "zod"; @@ -30,7 +29,7 @@ const searchParamsSchema = z.object({ export type SearchParams = z.infer; -export const loader = unstable_defineLoader(async ({ request, params }) => { +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); @@ -46,9 +45,9 @@ export const loader = unstable_defineLoader(async ({ request, params }) => { query[pageQueryParam], ); return { query, genreDetails, cookieName, totalPages }; -}); +}; -export const meta = ({ data }: MetaArgs_SingleFetch) => { +export const meta = ({ data }: MetaArgs) => { return [{ title: `${data?.genreDetails.details.name} | Ryot` }]; }; diff --git a/apps/frontend/app/routes/_dashboard.media.genre.list.tsx b/apps/frontend/app/routes/_dashboard.media.genre.list.tsx index 86c8253079..6f76c6d722 100644 --- a/apps/frontend/app/routes/_dashboard.media.genre.list.tsx +++ b/apps/frontend/app/routes/_dashboard.media.genre.list.tsx @@ -12,12 +12,8 @@ import { Text, Title, } from "@mantine/core"; -import { unstable_defineLoader } from "@remix-run/node"; -import { - Link, - type MetaArgs_SingleFetch, - useLoaderData, -} from "@remix-run/react"; +import type { LoaderFunctionArgs, MetaArgs } from "@remix-run/node"; +import { Link, useLoaderData } from "@remix-run/react"; import { GenreDetailsDocument, GenresListDocument, @@ -61,7 +57,7 @@ const searchParamsSchema = z.object({ export type SearchParams = z.infer; -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const cookieName = await getEnhancedCookieName("genre.list", request); await redirectUsingEnhancedCookieSearchParams(request, cookieName); const query = zx.parseQuery(request, searchParamsSchema); @@ -76,9 +72,9 @@ export const loader = unstable_defineLoader(async ({ request }) => { query[pageQueryParam], ); return { query, genresList, cookieName, totalPages }; -}); +}; -export const meta = (_args: MetaArgs_SingleFetch) => { +export const meta = (_args: MetaArgs) => { return [{ title: "Genres | Ryot" }]; }; diff --git a/apps/frontend/app/routes/_dashboard.media.groups.$action.tsx b/apps/frontend/app/routes/_dashboard.media.groups.$action.tsx index 516acdb78a..485210de16 100644 --- a/apps/frontend/app/routes/_dashboard.media.groups.$action.tsx +++ b/apps/frontend/app/routes/_dashboard.media.groups.$action.tsx @@ -15,12 +15,8 @@ import { Title, } from "@mantine/core"; import { useDisclosure } from "@mantine/hooks"; -import { unstable_defineLoader } from "@remix-run/node"; -import { - type MetaArgs_SingleFetch, - useLoaderData, - useNavigate, -} from "@remix-run/react"; +import type { LoaderFunctionArgs, MetaArgs } from "@remix-run/node"; +import { useLoaderData, useNavigate } from "@remix-run/react"; import { EntityLot, GraphqlSortOrder, @@ -84,7 +80,7 @@ const SEARCH_SOURCES_ALLOWED: Partial> = { [MediaSource.Igdb]: MediaLot.VideoGame, }; -export const loader = unstable_defineLoader(async ({ request, params }) => { +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, { @@ -159,9 +155,9 @@ export const loader = unstable_defineLoader(async ({ request, params }) => { cookieName, [pageQueryParam]: query[pageQueryParam], }; -}); +}; -export const meta = ({ params }: MetaArgs_SingleFetch) => { +export const meta = ({ params }: MetaArgs) => { return [{ title: `${changeCase(params.action || "")} Groups | Ryot` }]; }; 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 bf0e409270..f3f1b146a2 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 @@ -10,8 +10,7 @@ import { Text, Title, } from "@mantine/core"; -import { unstable_defineLoader } from "@remix-run/node"; -import type { MetaArgs_SingleFetch } from "@remix-run/react"; +import type { LoaderFunctionArgs, MetaArgs } from "@remix-run/node"; import { useLoaderData } from "@remix-run/react"; import { EntityLot, @@ -45,7 +44,7 @@ const searchParamsSchema = z.object({ export type SearchParams = z.infer; -export const loader = unstable_defineLoader(async ({ request, params }) => { +export const loader = async ({ request, params }: LoaderFunctionArgs) => { const { id: metadataGroupId } = zx.parseParams(params, { id: z.string() }); const query = zx.parseQuery(request, searchParamsSchema); const [{ metadataGroupDetails }, { userMetadataGroupDetails }] = @@ -65,9 +64,9 @@ export const loader = unstable_defineLoader(async ({ request, params }) => { metadataGroupDetails, userMetadataGroupDetails, }; -}); +}; -export const meta = ({ data }: MetaArgs_SingleFetch) => { +export const meta = ({ data }: MetaArgs) => { return [{ title: `${data?.metadataGroupDetails.details.title} | Ryot` }]; }; 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 337ecb9b96..152f6d13b6 100644 --- a/apps/frontend/app/routes/_dashboard.media.item.$id._index.tsx +++ b/apps/frontend/app/routes/_dashboard.media.item.$id._index.tsx @@ -32,13 +32,12 @@ import { import { DateInput } from "@mantine/dates"; import { useDidUpdate, useDisclosure, useInViewport } from "@mantine/hooks"; import { notifications } from "@mantine/notifications"; -import { unstable_defineAction, unstable_defineLoader } from "@remix-run/node"; -import { - Form, - Link, - type MetaArgs_SingleFetch, - useLoaderData, -} from "@remix-run/react"; +import type { + ActionFunctionArgs, + LoaderFunctionArgs, + MetaArgs, +} from "@remix-run/node"; +import { Form, Link, useLoaderData } from "@remix-run/react"; import { DeleteSeenItemDocument, DisassociateMetadataDocument, @@ -59,6 +58,7 @@ import { import { changeCase, formatDateToNaiveDate, + getActionIntent, humanizeDuration, isInteger, isNumber, @@ -91,7 +91,6 @@ import { } from "react"; import { Virtuoso, VirtuosoGrid, type VirtuosoHandle } from "react-virtuoso"; import { $path } from "remix-routes"; -import { namedAction } from "remix-utils/named-action"; import { match } from "ts-pattern"; import { withQuery } from "ufo"; import { z } from "zod"; @@ -147,7 +146,7 @@ const searchParamsSchema = z export type SearchParams = z.infer; -export const loader = unstable_defineLoader(async ({ request, params }) => { +export const loader = async ({ request, params }: LoaderFunctionArgs) => { const { id: metadataId } = zx.parseParams(params, { id: z.string() }); const query = zx.parseQuery(request, searchParamsSchema); const [{ metadataDetails }, { userMetadataDetails }] = await Promise.all([ @@ -159,16 +158,17 @@ export const loader = unstable_defineLoader(async ({ request, params }) => { ), ]); return { query, metadataId, metadataDetails, userMetadataDetails }; -}); +}; -export const meta = ({ data }: MetaArgs_SingleFetch) => { +export const meta = ({ data }: MetaArgs) => { return [{ title: `${data?.metadataDetails.title} | Ryot` }]; }; -export const action = unstable_defineAction(async ({ request }) => { +export const action = async ({ request }: ActionFunctionArgs) => { const formData = await request.clone().formData(); - return namedAction(request, { - deleteSeenItem: async () => { + const intent = getActionIntent(request); + return await match(intent) + .with("deleteSeenItem", async () => { const submission = processSubmission(formData, seenIdSchema); await serverGqlService.authenticatedRequest( request, @@ -181,8 +181,8 @@ export const action = unstable_defineAction(async ({ request }) => { message: "Record deleted successfully", }), }); - }, - mergeMetadata: async () => { + }) + .with("mergeMetadata", async () => { const submission = processSubmission(formData, mergeMetadataSchema); await serverGqlService.authenticatedRequest( request, @@ -193,8 +193,8 @@ export const action = unstable_defineAction(async ({ request }) => { $path("/media/item/:id", { id: submission.mergeInto }), { type: "success", message: "Metadata merged successfully" }, ); - }, - editSeenItem: async () => { + }) + .with("editSeenItem", async () => { const submission = processSubmission(formData, editSeenItem); submission.reviewId = submission.reviewId || ""; await serverGqlService.authenticatedRequest( @@ -208,8 +208,8 @@ export const action = unstable_defineAction(async ({ request }) => { message: "Edited history item successfully", }), }); - }, - removeItem: async () => { + }) + .with("removeItem", async () => { const submission = processSubmission(formData, MetadataIdSchema); await serverGqlService.authenticatedRequest( request, @@ -220,9 +220,9 @@ export const action = unstable_defineAction(async ({ request }) => { type: "success", message: "Removed item successfully", }); - }, - }); -}); + }) + .run(); +}; const seenIdSchema = z.object({ seenId: z.string() }); @@ -718,42 +718,38 @@ export default function Page() { nextEntry ? ( <> Anime - <> - { - setMetadataToUpdate({ - metadataId: loaderData.metadataId, - animeEpisodeNumber: nextEntry.episode, - }); - }} - > - Mark EP- - {nextEntry.episode} as listened - - + { + setMetadataToUpdate({ + metadataId: loaderData.metadataId, + animeEpisodeNumber: nextEntry.episode, + }); + }} + > + Mark EP- + {nextEntry.episode} as listened + ) : null} {loaderData.metadataDetails.lot === MediaLot.Manga && nextEntry ? ( <> Manga - <> - { - setMetadataToUpdate({ - metadataId: loaderData.metadataId, - mangaChapterNumber: nextEntry.chapter, - mangaVolumeNumber: nextEntry.volume, - }); - }} - > - Mark{" "} - {nextEntry.chapter - ? `CH-${nextEntry.chapter}` - : `VOL-${nextEntry.volume}`}{" "} - as read - - + { + setMetadataToUpdate({ + metadataId: loaderData.metadataId, + mangaChapterNumber: nextEntry.chapter, + mangaVolumeNumber: nextEntry.volume, + }); + }} + > + Mark{" "} + {nextEntry.chapter + ? `CH-${nextEntry.chapter}` + : `VOL-${nextEntry.volume}`}{" "} + as read + ) : null} {loaderData.metadataDetails.lot === MediaLot.Podcast ? ( @@ -1801,25 +1797,23 @@ const DisplayShowSeason = (props: { .map((e) => e.runtime || 0) .reduce((i, a) => i + a, 0)} > - <> - {props.season.episodes.length > 0 ? ( - - ) : null} - + {props.season.episodes.length > 0 ? ( + + ) : null} ); }; diff --git a/apps/frontend/app/routes/_dashboard.media.people.$action.tsx b/apps/frontend/app/routes/_dashboard.media.people.$action.tsx index ab248f265c..3262a86e8f 100644 --- a/apps/frontend/app/routes/_dashboard.media.people.$action.tsx +++ b/apps/frontend/app/routes/_dashboard.media.people.$action.tsx @@ -15,12 +15,8 @@ import { Title, } from "@mantine/core"; import { useDisclosure } from "@mantine/hooks"; -import { unstable_defineLoader } from "@remix-run/node"; -import { - type MetaArgs_SingleFetch, - useLoaderData, - useNavigate, -} from "@remix-run/react"; +import type { LoaderFunctionArgs, MetaArgs } from "@remix-run/node"; +import { useLoaderData, useNavigate } from "@remix-run/react"; import { EntityLot, GraphqlSortOrder, @@ -85,7 +81,7 @@ const SEARCH_SOURCES_ALLOWED = [ MediaSource.Igdb, ] as const; -export const loader = unstable_defineLoader(async ({ request, params }) => { +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); @@ -162,9 +158,9 @@ export const loader = unstable_defineLoader(async ({ request, params }) => { peopleSearch, [pageQueryParam]: query[pageQueryParam], }; -}); +}; -export const meta = ({ params }: MetaArgs_SingleFetch) => { +export const meta = ({ params }: MetaArgs) => { return [{ title: `${changeCase(params.action || "")} People | Ryot` }]; }; 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 7c228b7be6..a0b434f757 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 @@ -11,8 +11,8 @@ import { Text, Title, } from "@mantine/core"; -import { unstable_defineLoader } from "@remix-run/node"; -import { type MetaArgs_SingleFetch, useLoaderData } from "@remix-run/react"; +import type { LoaderFunctionArgs, MetaArgs } from "@remix-run/node"; +import { useLoaderData } from "@remix-run/react"; import { EntityLot, PersonDetailsDocument, @@ -48,7 +48,7 @@ const searchParamsSchema = z.object({ export type SearchParams = z.infer; -export const loader = unstable_defineLoader(async ({ request, params }) => { +export const loader = async ({ request, params }: LoaderFunctionArgs) => { const { id: personId } = zx.parseParams(params, { id: z.string() }); const query = zx.parseQuery(request, searchParamsSchema); const [{ personDetails }, { userPersonDetails }] = await Promise.all([ @@ -58,9 +58,9 @@ export const loader = unstable_defineLoader(async ({ request, params }) => { }), ]); return { query, personId, userPersonDetails, personDetails }; -}); +}; -export const meta = ({ data }: MetaArgs_SingleFetch) => { +export const meta = ({ data }: MetaArgs) => { return [{ title: `${data?.personDetails.details.name} | Ryot` }]; }; diff --git a/apps/frontend/app/routes/_dashboard.settings.imports-and-exports._index.tsx b/apps/frontend/app/routes/_dashboard.settings.imports-and-exports._index.tsx index f8a0f3620d..e0412f4828 100644 --- a/apps/frontend/app/routes/_dashboard.settings.imports-and-exports._index.tsx +++ b/apps/frontend/app/routes/_dashboard.settings.imports-and-exports._index.tsx @@ -22,15 +22,12 @@ import { Tooltip, } from "@mantine/core"; import { - unstable_defineAction, - unstable_defineLoader, + type ActionFunctionArgs, + type LoaderFunctionArgs, + type MetaArgs, unstable_parseMultipartFormData, } from "@remix-run/node"; -import { - Form, - type MetaArgs_SingleFetch, - useLoaderData, -} from "@remix-run/react"; +import { Form, useLoaderData } from "@remix-run/react"; import { DeployExportJobDocument, DeployImportJobDocument, @@ -38,11 +35,10 @@ import { ImportSource, UserExportsDocument, } from "@ryot/generated/graphql/backend/graphql"; -import { changeCase, processSubmission } from "@ryot/ts-utils"; +import { changeCase, getActionIntent, processSubmission } from "@ryot/ts-utils"; import { IconDownload } from "@tabler/icons-react"; import { filesize } from "filesize"; -import { type ReactNode, useState } from "react"; -import { namedAction } from "remix-utils/named-action"; +import { useState } from "react"; import { match } from "ts-pattern"; import { withFragment, withQuery } from "ufo"; import { z } from "zod"; @@ -57,25 +53,26 @@ import { import { createToastHeaders, serverGqlService } from "~/lib/utilities.server"; import { temporaryFileUploadHandler } from "~/lib/utilities.server"; -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const [{ importReports }, { userExports }] = await Promise.all([ serverGqlService.authenticatedRequest(request, ImportReportsDocument, {}), serverGqlService.authenticatedRequest(request, UserExportsDocument, {}), ]); return { importReports, userExports }; -}); +}; -export const meta = (_args: MetaArgs_SingleFetch) => { +export const meta = (_args: MetaArgs) => { return [{ title: "Imports and Exports | Ryot" }]; }; -export const action = unstable_defineAction(async ({ request }) => { +export const action = async ({ request }: ActionFunctionArgs) => { const formData = await unstable_parseMultipartFormData( request.clone(), temporaryFileUploadHandler, ); - return namedAction(request, { - deployImport: async () => { + const intent = getActionIntent(request); + return await match(intent) + .with("deployImport", async () => { const source = formData.get("source") as ImportSource; formData.delete("source"); const values = await match(source) @@ -133,8 +130,8 @@ export const action = unstable_defineAction(async ({ request }) => { }), }, ); - }, - deployExport: async () => { + }) + .with("deployExport", async () => { await serverGqlService.authenticatedRequest( request, DeployExportJobDocument, @@ -149,9 +146,9 @@ export const action = unstable_defineAction(async ({ request }) => { }), }, ); - }, - }); -}); + }) + .run(); +}; const usernameImportFormSchema = z.object({ username: z.string() }); @@ -194,6 +191,7 @@ const malImportFormSchema = z.object({ export default function Page() { const loaderData = useLoaderData(); const coreDetails = useCoreDetails(); + const submit = useConfirmSubmit(); const fileUploadNotAllowed = !coreDetails.fileStorageEnabled; const userCollections = useUserCollections(); const events = useApplicationEvents(); @@ -262,7 +260,7 @@ export default function Page() { }} /> {deployImportSource ? ( - + <> {match(deployImportSource) .with( ImportSource.Audiobookshelf, @@ -283,7 +281,6 @@ export default function Page() { ), ) - .with( ImportSource.OpenScale, ImportSource.Goodreads, @@ -423,7 +420,26 @@ export default function Page() { )) .exhaustive()} - + + ) : null} Import history @@ -503,15 +519,19 @@ export default function Page() { - + - - ); -}; diff --git a/apps/frontend/app/routes/_dashboard.settings.integrations.tsx b/apps/frontend/app/routes/_dashboard.settings.integrations.tsx index 0bf11adb20..d83a138aac 100644 --- a/apps/frontend/app/routes/_dashboard.settings.integrations.tsx +++ b/apps/frontend/app/routes/_dashboard.settings.integrations.tsx @@ -21,8 +21,11 @@ import { Tooltip, } from "@mantine/core"; import { useDisclosure } from "@mantine/hooks"; -import { unstable_defineAction, unstable_defineLoader } from "@remix-run/node"; -import type { MetaArgs_SingleFetch } from "@remix-run/react"; +import type { + ActionFunctionArgs, + LoaderFunctionArgs, + MetaArgs, +} from "@remix-run/node"; import { Form, useActionData, useLoaderData } from "@remix-run/react"; import { CreateUserIntegrationDocument, @@ -34,7 +37,7 @@ import { UserIntegrationsDocument, type UserIntegrationsQuery, } from "@ryot/generated/graphql/backend/graphql"; -import { changeCase, processSubmission } from "@ryot/ts-utils"; +import { changeCase, getActionIntent, processSubmission } from "@ryot/ts-utils"; import { IconCheck, IconCopy, @@ -44,15 +47,14 @@ import { IconTrash, } from "@tabler/icons-react"; import { useState } from "react"; -import { namedAction } from "remix-utils/named-action"; import { match } from "ts-pattern"; import { withQuery } from "ufo"; import { z } from "zod"; import { zx } from "zodix"; import { confirmWrapper } from "~/components/confirmation"; import { + PRO_REQUIRED_MESSAGE, applicationBaseUrl, - commaDelimitedString, dayjsLib, } from "~/lib/generals"; import { @@ -62,6 +64,7 @@ import { } from "~/lib/hooks"; import { createToastHeaders, serverGqlService } from "~/lib/utilities.server"; +const PRO_INTEGRATIONS = [IntegrationProvider.JellyfinPush]; const YANK_INTEGRATIONS = [ IntegrationProvider.Audiobookshelf, IntegrationProvider.Komga, @@ -69,10 +72,11 @@ const YANK_INTEGRATIONS = [ const PUSH_INTEGRATIONS = [ IntegrationProvider.Radarr, IntegrationProvider.Sonarr, + IntegrationProvider.JellyfinPush, ]; const NO_SHOW_URL = [...YANK_INTEGRATIONS, ...PUSH_INTEGRATIONS]; -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const [{ userIntegrations }] = await Promise.all([ serverGqlService.authenticatedRequest( request, @@ -81,16 +85,17 @@ export const loader = unstable_defineLoader(async ({ request }) => { ), ]); return { userIntegrations }; -}); +}; -export const meta = (_args: MetaArgs_SingleFetch) => { +export const meta = (_args: MetaArgs) => { return [{ title: "Integration Settings | Ryot" }]; }; -export const action = unstable_defineAction(async ({ request }) => { +export const action = async ({ request }: ActionFunctionArgs) => { const formData = await request.clone().formData(); - return namedAction(request, { - delete: async () => { + const intent = getActionIntent(request); + return await match(intent) + .with("delete", async () => { const submission = processSubmission(formData, deleteSchema); await serverGqlService.authenticatedRequest( request, @@ -106,8 +111,8 @@ export const action = unstable_defineAction(async ({ request }) => { }), }, ); - }, - create: async () => { + }) + .with("create", async () => { const submission = processSubmission(formData, createSchema); await serverGqlService.authenticatedRequest( request, @@ -123,8 +128,8 @@ export const action = unstable_defineAction(async ({ request }) => { }), }, ); - }, - update: async () => { + }) + .with("update", async () => { const submission = processSubmission(formData, updateSchema); // DEV: Reason for this: https://stackoverflow.com/a/11424089/11667450 submission.isDisabled = submission.isDisabled === true; @@ -142,47 +147,27 @@ export const action = unstable_defineAction(async ({ request }) => { }), }, ); - }, - generateAuthToken: async () => { + }) + .with("generateAuthToken", async () => { const { generateAuthToken } = await serverGqlService.authenticatedRequest( request, GenerateAuthTokenDocument, {}, ); return Response.json({ status: "success", generateAuthToken } as const); - }, - }); -}); + }) + .run(); +}; const MINIMUM_PROGRESS = "2"; const MAXIMUM_PROGRESS = "95"; const createSchema = z.object({ - provider: z.nativeEnum(IntegrationProvider), + providerSpecifics: z.any().optional(), minimumProgress: z.string().optional(), maximumProgress: z.string().optional(), + provider: z.nativeEnum(IntegrationProvider), syncToOwnedCollection: zx.CheckboxAsString.optional(), - providerSpecifics: z - .object({ - plexUsername: z.string().optional(), - audiobookshelfBaseUrl: z.string().optional(), - audiobookshelfToken: z.string().optional(), - komgaBaseUrl: z.string().optional(), - komgaUsername: z.string().optional(), - komgaPassword: z.string().optional(), - komgaProvider: z.nativeEnum(MediaSource).optional(), - radarrBaseUrl: z.string().optional(), - radarrApiKey: z.string().optional(), - radarrProfileId: z.number().optional(), - radarrRootFolderPath: z.string().optional(), - radarrSyncCollectionIds: commaDelimitedString, - sonarrBaseUrl: z.string().optional(), - sonarrApiKey: z.string().optional(), - sonarrProfileId: z.number().optional(), - sonarrRootFolderPath: z.string().optional(), - sonarrSyncCollectionIds: commaDelimitedString, - }) - .optional(), }); const deleteSchema = z.object({ @@ -392,7 +377,9 @@ const CreateIntegrationModal = (props: { closeIntegrationModal: () => void; }) => { const coreDetails = useCoreDetails(); - const [provider, setProvider] = useState(null); + const [provider, setProvider] = useState(); + const disableCreationButton = + !coreDetails.isPro && provider && PRO_INTEGRATIONS.includes(provider); return ( )) + .with(IntegrationProvider.JellyfinPush, () => ( + <> + + + + + )) .with(IntegrationProvider.Radarr, () => ) .with(IntegrationProvider.Sonarr, () => ) .otherwise(() => undefined)} @@ -510,7 +516,14 @@ const CreateIntegrationModal = (props: { /> ) : undefined} - + + + diff --git a/apps/frontend/app/routes/_dashboard.settings.miscellaneous.tsx b/apps/frontend/app/routes/_dashboard.settings.miscellaneous.tsx index 8b567d64fc..ec6b124237 100644 --- a/apps/frontend/app/routes/_dashboard.settings.miscellaneous.tsx +++ b/apps/frontend/app/routes/_dashboard.settings.miscellaneous.tsx @@ -7,8 +7,8 @@ import { Text, Title, } from "@mantine/core"; -import { unstable_defineAction } from "@remix-run/node"; -import { Form, type MetaArgs_SingleFetch } from "@remix-run/react"; +import type { ActionFunctionArgs, MetaArgs } from "@remix-run/node"; +import { Form, data } from "@remix-run/react"; import { BackgroundJob, DeployBackgroundJobDocument, @@ -19,11 +19,11 @@ import { z } from "zod"; import { useDashboardLayoutData, useUserDetails } from "~/lib/hooks"; import { createToastHeaders, serverGqlService } from "~/lib/utilities.server"; -export const meta = (_args: MetaArgs_SingleFetch) => { +export const meta = (_args: MetaArgs) => { return [{ title: "Miscellaneous settings | Ryot" }]; }; -export const action = unstable_defineAction(async ({ request }) => { +export const action = async ({ request }: ActionFunctionArgs) => { const formData = await request.clone().formData(); const submission = processSubmission(formData, jobSchema); await serverGqlService.authenticatedRequest( @@ -31,13 +31,13 @@ export const action = unstable_defineAction(async ({ request }) => { DeployBackgroundJobDocument, submission, ); - return Response.json({ status: "success" } as const, { + return data({} as const, { headers: await createToastHeaders({ type: "success", message: "Job has been deployed", }), }); -}); +}; const jobSchema = z.object({ jobName: z.nativeEnum(BackgroundJob), diff --git a/apps/frontend/app/routes/_dashboard.settings.notifications.tsx b/apps/frontend/app/routes/_dashboard.settings.notifications.tsx index cf6151d353..36f9b00f50 100644 --- a/apps/frontend/app/routes/_dashboard.settings.notifications.tsx +++ b/apps/frontend/app/routes/_dashboard.settings.notifications.tsx @@ -17,12 +17,12 @@ import { Tooltip, } from "@mantine/core"; import { useDisclosure } from "@mantine/hooks"; -import { unstable_defineAction, unstable_defineLoader } from "@remix-run/node"; -import { - Form, - type MetaArgs_SingleFetch, - useLoaderData, -} from "@remix-run/react"; +import type { + ActionFunctionArgs, + LoaderFunctionArgs, + MetaArgs, +} from "@remix-run/node"; +import { Form, useLoaderData } from "@remix-run/react"; import { CreateUserNotificationPlatformDocument, DeleteUserNotificationPlatformDocument, @@ -32,14 +32,13 @@ import { UserNotificationPlatformsDocument, type UserNotificationPlatformsQuery, } from "@ryot/generated/graphql/backend/graphql"; -import { changeCase, processSubmission } from "@ryot/ts-utils"; +import { changeCase, getActionIntent, processSubmission } from "@ryot/ts-utils"; import { IconPlayerPause, IconPlayerPlay, IconTrash, } from "@tabler/icons-react"; import { useState } from "react"; -import { namedAction } from "remix-utils/named-action"; import { match } from "ts-pattern"; import { withQuery } from "ufo"; import { z } from "zod"; @@ -49,7 +48,7 @@ import { dayjsLib } from "~/lib/generals"; import { useConfirmSubmit, useCoreDetails } from "~/lib/hooks"; import { createToastHeaders, serverGqlService } from "~/lib/utilities.server"; -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const [{ userNotificationPlatforms }] = await Promise.all([ serverGqlService.authenticatedRequest( request, @@ -58,16 +57,17 @@ export const loader = unstable_defineLoader(async ({ request }) => { ), ]); return { userNotificationPlatforms }; -}); +}; -export const meta = (_args: MetaArgs_SingleFetch) => { +export const meta = (_args: MetaArgs) => { return [{ title: "Notification Settings | Ryot" }]; }; -export const action = unstable_defineAction(async ({ request }) => { +export const action = async ({ request }: ActionFunctionArgs) => { const formData = await request.clone().formData(); - return namedAction(request, { - create: async () => { + const intent = getActionIntent(request); + return await match(intent) + .with("create", async () => { const submission = processSubmission(formData, createSchema); await serverGqlService.authenticatedRequest( request, @@ -75,8 +75,8 @@ export const action = unstable_defineAction(async ({ request }) => { { input: submission }, ); return Response.json({ status: "success", submission } as const); - }, - delete: async () => { + }) + .with("delete", async () => { const submission = processSubmission(formData, deleteSchema); await serverGqlService.authenticatedRequest( request, @@ -89,8 +89,8 @@ export const action = unstable_defineAction(async ({ request }) => { message: "Notification platform deleted successfully", }), }); - }, - test: async () => { + }) + .with("test", async () => { const { testUserNotificationPlatforms } = await serverGqlService.authenticatedRequest( request, @@ -105,8 +105,8 @@ export const action = unstable_defineAction(async ({ request }) => { : "Something went wrong", }), }); - }, - update: async () => { + }) + .with("update", async () => { const submission = processSubmission(formData, updateSchema); submission.isDisabled = submission.isDisabled === true; await serverGqlService.authenticatedRequest( @@ -120,9 +120,9 @@ export const action = unstable_defineAction(async ({ request }) => { message: "Notification updated successfully", }), }); - }, - }); -}); + }) + .run(); +}; const deleteSchema = z.object({ notificationId: z.string() }); diff --git a/apps/frontend/app/routes/_dashboard.settings.preferences.tsx b/apps/frontend/app/routes/_dashboard.settings.preferences.tsx index 6a203782f2..e8a5cbf43a 100644 --- a/apps/frontend/app/routes/_dashboard.settings.preferences.tsx +++ b/apps/frontend/app/routes/_dashboard.settings.preferences.tsx @@ -25,9 +25,12 @@ import { rem, } from "@mantine/core"; import { notifications } from "@mantine/notifications"; -import { unstable_defineAction, unstable_defineLoader } from "@remix-run/node"; -import type { MetaArgs_SingleFetch } from "@remix-run/react"; -import { Form, useLoaderData } from "@remix-run/react"; +import type { + ActionFunctionArgs, + LoaderFunctionArgs, + MetaArgs, +} from "@remix-run/node"; +import { Form, data, useLoaderData } from "@remix-run/react"; import { type DashboardElementLot, GridPacking, @@ -76,13 +79,13 @@ const searchSchema = z.object({ defaultTab: z.string().default("dashboard").optional(), }); -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const query = zx.parseQuery(request, searchSchema); const workoutInProgress = isWorkoutActive(request); return { query, workoutInProgress }; -}); +}; -export const meta = (_args: MetaArgs_SingleFetch) => { +export const meta = (_args: MetaArgs) => { return [{ title: "Preference | Ryot" }]; }; @@ -93,7 +96,7 @@ const notificationContent = { "Changing preferences is disabled for demo users. Please create an account to save your preferences.", }; -export const action = unstable_defineAction(async ({ request }) => { +export const action = async ({ request }: ActionFunctionArgs) => { const userDetails = await redirectIfNotAuthenticatedOrUpdated(request); const entries = Object.entries(Object.fromEntries(await request.formData())); const submission = []; @@ -121,8 +124,8 @@ export const action = unstable_defineAction(async ({ request }) => { message: "Preferences updated", type: "success", }); - return Response.json({}, { headers: toastHeaders }); -}); + return data({}, { headers: toastHeaders }); +}; export default function Page() { const loaderData = useLoaderData(); diff --git a/apps/frontend/app/routes/_dashboard.settings.profile-and-sharing.tsx b/apps/frontend/app/routes/_dashboard.settings.profile-and-sharing.tsx index 3fe089131b..35d6e970c9 100644 --- a/apps/frontend/app/routes/_dashboard.settings.profile-and-sharing.tsx +++ b/apps/frontend/app/routes/_dashboard.settings.profile-and-sharing.tsx @@ -22,12 +22,12 @@ import { } from "@mantine/core"; import { DateTimePicker } from "@mantine/dates"; import { useDisclosure } from "@mantine/hooks"; -import { unstable_defineAction, unstable_defineLoader } from "@remix-run/node"; -import { - Form, - type MetaArgs_SingleFetch, - useLoaderData, -} from "@remix-run/react"; +import type { + ActionFunctionArgs, + LoaderFunctionArgs, + MetaArgs, +} from "@remix-run/node"; +import { Form, useLoaderData } from "@remix-run/react"; import { CreateAccessLinkDocument, RevokeAccessLinkDocument, @@ -35,7 +35,12 @@ import { UserAccessLinksDocument, type UserAccessLinksQuery, } from "@ryot/generated/graphql/backend/graphql"; -import { isNumber, isString, processSubmission } from "@ryot/ts-utils"; +import { + getActionIntent, + isNumber, + isString, + processSubmission, +} from "@ryot/ts-utils"; import { IconEye, IconEyeClosed, @@ -43,7 +48,7 @@ import { IconLockAccess, } from "@tabler/icons-react"; import { ClientOnly } from "remix-utils/client-only"; -import { namedAction } from "remix-utils/named-action"; +import { match } from "ts-pattern"; import { withQuery } from "ufo"; import { z } from "zod"; import { zx } from "zodix"; @@ -66,28 +71,29 @@ import { serverGqlService, } from "~/lib/utilities.server"; -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const [{ userAccessLinks }] = await Promise.all([ serverGqlService.authenticatedRequest(request, UserAccessLinksDocument, {}), ]); return { userAccessLinks }; -}); +}; -export const meta = (_args: MetaArgs_SingleFetch) => { +export const meta = (_args: MetaArgs) => { return [{ title: "Profile and Sharing | Ryot" }]; }; -export const action = unstable_defineAction(async ({ request }) => { +export const action = async ({ request }: ActionFunctionArgs) => { const formData = await request.formData(); - return namedAction(request, { - updateProfile: async () => { + const intent = getActionIntent(request); + return await match(intent) + .with("updateProfile", async () => { const token = getAuthorizationCookie(request); const submission = processSubmission(formData, updateProfileFormSchema); await serverGqlService.authenticatedRequest(request, UpdateUserDocument, { input: submission, }); queryClient.removeQueries({ - queryKey: queryFactory.users.details(token).queryKey, + queryKey: queryFactory.users.details(token ?? "").queryKey, }); return Response.json({ status: "success", submission } as const, { headers: await createToastHeaders({ @@ -95,8 +101,8 @@ export const action = unstable_defineAction(async ({ request }) => { message: "Profile updated successfully", }), }); - }, - revokeAccessLink: async () => { + }) + .with("revokeAccessLink", async () => { const submission = processSubmission( formData, revokeAccessLinkFormSchema, @@ -112,8 +118,8 @@ export const action = unstable_defineAction(async ({ request }) => { message: "Access link revoked successfully", }), }); - }, - createAccessLink: async () => { + }) + .with("createAccessLink", async () => { const submission = processSubmission( formData, createAccessLinkFormSchema, @@ -130,8 +136,8 @@ export const action = unstable_defineAction(async ({ request }) => { message: "Access link created successfully", }), }); - }, - createDefaultAccessLink: async () => { + }) + .with("createDefaultAccessLink", async () => { await serverGqlService.authenticatedRequest( request, CreateAccessLinkDocument, @@ -143,9 +149,9 @@ export const action = unstable_defineAction(async ({ request }) => { message: "Account default access link created successfully", }), }); - }, - }); -}); + }) + .run(); +}; const updateProfileFormSchema = z.object({ userId: z.string(), @@ -285,8 +291,9 @@ export default function Page() { diff --git a/apps/frontend/app/routes/_dashboard.settings.users.tsx b/apps/frontend/app/routes/_dashboard.settings.users.tsx index 74a75ce0b1..8b6b8bbf7b 100644 --- a/apps/frontend/app/routes/_dashboard.settings.users.tsx +++ b/apps/frontend/app/routes/_dashboard.settings.users.tsx @@ -18,11 +18,11 @@ import { } from "@mantine/core"; import { useDisclosure } from "@mantine/hooks"; import { + type ActionFunctionArgs, + type LoaderFunctionArgs, + type MetaArgs, redirect, - unstable_defineAction, - unstable_defineLoader, } from "@remix-run/node"; -import type { MetaArgs_SingleFetch } from "@remix-run/react"; import { Form, useLoaderData } from "@remix-run/react"; import { DeleteUserDocument, @@ -35,6 +35,7 @@ import { } from "@ryot/generated/graphql/backend/graphql"; import { changeCase, + getActionIntent, processSubmission, randomString, truncate, @@ -48,7 +49,6 @@ import { import { forwardRef, useState } from "react"; import { VirtuosoGrid } from "react-virtuoso"; import { $path } from "remix-routes"; -import { namedAction } from "remix-utils/named-action"; import { match } from "ts-pattern"; import { withQuery } from "ufo"; import { z } from "zod"; @@ -70,7 +70,7 @@ const searchParamsSchema = z.object({ export type SearchParams = z.infer; -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const userDetails = await redirectIfNotAuthenticatedOrUpdated(request); if (userDetails.lot !== UserLot.Admin) throw redirect($path("/")); const cookieName = await getEnhancedCookieName("settings.users", request); @@ -82,16 +82,17 @@ export const loader = unstable_defineLoader(async ({ request }) => { }), ]); return { usersList, query, cookieName }; -}); +}; -export const meta = (_args: MetaArgs_SingleFetch) => { +export const meta = (_args: MetaArgs) => { return [{ title: "User Settings | Ryot" }]; }; -export const action = unstable_defineAction(async ({ request }) => { +export const action = async ({ request }: ActionFunctionArgs) => { const formData = await request.clone().formData(); - return namedAction(request, { - delete: async () => { + const intent = getActionIntent(request); + return await match(intent) + .with("delete", async () => { const submission = processSubmission(formData, deleteSchema); const { deleteUser } = await serverGqlService.authenticatedRequest( request, @@ -106,8 +107,8 @@ export const action = unstable_defineAction(async ({ request }) => { : "User can not be deleted", }), }); - }, - registerNew: async () => { + }) + .with("registerNew", async () => { const submission = processSubmission(formData, registerFormSchema); const { registerUser } = await serverGqlService.authenticatedRequest( request, @@ -142,8 +143,8 @@ export const action = unstable_defineAction(async ({ request }) => { .exhaustive(), }), }); - }, - update: async () => { + }) + .with("update", async () => { const submission = processSubmission(formData, updateUserSchema); submission.isDisabled = submission.isDisabled === true; await serverGqlService.authenticatedRequest(request, UpdateUserDocument, { @@ -155,9 +156,9 @@ export const action = unstable_defineAction(async ({ request }) => { message: "User updated successfully", }), }); - }, - }); -}); + }) + .run(); +}; const registerFormSchema = z.object({ username: z.string(), @@ -205,8 +206,12 @@ export default function Page() { withCloseButton={false} centered > -
- + Create User diff --git a/apps/frontend/app/routes/_dashboard.tsx b/apps/frontend/app/routes/_dashboard.tsx index 6e5b43a088..f686c5bbd2 100644 --- a/apps/frontend/app/routes/_dashboard.tsx +++ b/apps/frontend/app/routes/_dashboard.tsx @@ -47,7 +47,6 @@ import { useDisclosure, useLocalStorage, } from "@mantine/hooks"; -import { unstable_defineLoader } from "@remix-run/node"; import { Form, Link, @@ -145,12 +144,13 @@ import { } from "~/lib/utilities.server"; import { colorSchemeCookie } from "~/lib/utilities.server"; import "@mantine/dates/styles.css"; +import type { LoaderFunctionArgs } from "@remix-run/node"; import { useBulkEditCollection } from "~/lib/state/collection"; import classes from "~/styles/dashboard.module.css"; const discordLink = "https://discord.gg/D9XTg2a7R8"; -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const userDetails = await redirectIfNotAuthenticatedOrUpdated(request); const [userPreferences, userCollections, { coreDetails }] = await Promise.all( [ @@ -245,7 +245,7 @@ export const loader = unstable_defineLoader(async ({ request }) => { const decodedCookie = jwtDecode<{ access_link?: { id: string; is_demo?: boolean }; - }>(getAuthorizationCookie(request)); + }>(getAuthorizationCookie(request) ?? ""); const isAccessLinkSession = Boolean(decodedCookie?.access_link); const isDemo = Boolean(decodedCookie?.access_link?.is_demo); @@ -272,7 +272,7 @@ export const loader = unstable_defineLoader(async ({ request }) => { currentColorScheme, isAccessLinkSession, }; -}); +}; export function ErrorBoundary() { const error = useRouteError() as Error; diff --git a/apps/frontend/app/routes/actions.tsx b/apps/frontend/app/routes/actions.tsx index cfbbeacb17..87c5586aee 100644 --- a/apps/frontend/app/routes/actions.tsx +++ b/apps/frontend/app/routes/actions.tsx @@ -1,6 +1,6 @@ import { + type ActionFunctionArgs, redirect, - unstable_defineAction, unstable_parseMultipartFormData, } from "@remix-run/node"; import { @@ -24,6 +24,7 @@ import { Visibility, } from "@ryot/generated/graphql/backend/graphql"; import { + getActionIntent, isEmpty, isNumber, omitBy, @@ -54,11 +55,9 @@ const sleepForHalfSecond = async (request: Request) => export const loader = async () => redirect($path("/")); -export const action = unstable_defineAction(async ({ request }) => { +export const action = async ({ request }: ActionFunctionArgs) => { const formData = await request.clone().formData(); - const { searchParams } = new URL(request.url); - const intent = searchParams.get("intent") as string; - invariant(intent); + const intent = getActionIntent(request); const redirectToForm = formData.get(redirectToQueryParam); let redirectTo = redirectToForm ? redirectToForm.toString() : undefined; let returnData = {}; @@ -462,7 +461,7 @@ export const action = unstable_defineAction(async ({ request }) => { status = 302; } return Response.json(returnData, { headers, status }); -}); +}; const commitMediaSchema = z.object({ identifier: z.string(), diff --git a/apps/frontend/app/routes/api.auth.tsx b/apps/frontend/app/routes/api.auth.tsx index 2bc81b7352..6887c11f83 100644 --- a/apps/frontend/app/routes/api.auth.tsx +++ b/apps/frontend/app/routes/api.auth.tsx @@ -1,4 +1,4 @@ -import { redirect, unstable_defineLoader } from "@remix-run/node"; +import { type LoaderFunctionArgs, redirect } from "@remix-run/node"; import { GetOidcTokenDocument, LoginUserDocument, @@ -20,7 +20,7 @@ const searchParamsSchema = z.object({ code: z.string() }); export type SearchParams = z.infer; -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const input = zx.parseQuery(request, searchParamsSchema); const { getOidcToken } = await serverGqlService.request( GetOidcTokenDocument, @@ -59,4 +59,4 @@ export const loader = unstable_defineLoader(async ({ request }) => { } console.error("Login failed:", loginUser); return Response.json({ input }); -}); +}; diff --git a/apps/frontend/app/routes/api.sharing.$accessLinkId.tsx b/apps/frontend/app/routes/api.sharing.$accessLinkId.tsx index 0e00ae33f4..0fb65b6289 100644 --- a/apps/frontend/app/routes/api.sharing.$accessLinkId.tsx +++ b/apps/frontend/app/routes/api.sharing.$accessLinkId.tsx @@ -1,4 +1,4 @@ -import { redirect, unstable_defineLoader } from "@remix-run/node"; +import { type LoaderFunctionArgs, redirect } from "@remix-run/node"; import { ProcessAccessLinkDocument, type ProcessAccessLinkInput, @@ -21,7 +21,7 @@ const searchParamsSchema = z.object({ [redirectToQueryParam]: z.string().optional(), }); -export const loader = unstable_defineLoader(async ({ request, params }) => { +export const loader = async ({ request, params }: LoaderFunctionArgs) => { const query = zx.parseQuery(request, searchParamsSchema); const routeParams = zx.parseParams(params, paramsSchema); const input: ProcessAccessLinkInput = {}; @@ -53,4 +53,4 @@ export const loader = unstable_defineLoader(async ({ request, params }) => { message: `Encountered: ${processAccessLink.error}`, }), }); -}); +}; diff --git a/apps/frontend/app/routes/auth.tsx b/apps/frontend/app/routes/auth.tsx index 3e1033a3d3..d97b49d77b 100644 --- a/apps/frontend/app/routes/auth.tsx +++ b/apps/frontend/app/routes/auth.tsx @@ -11,17 +11,12 @@ import { TextInput, } from "@mantine/core"; import { + type ActionFunctionArgs, + type LoaderFunctionArgs, + type MetaArgs, redirect, - unstable_defineAction, - unstable_defineLoader, } from "@remix-run/node"; -import { - Form, - Link, - type MetaArgs_SingleFetch, - useLoaderData, - useSearchParams, -} from "@remix-run/react"; +import { Form, Link, useLoaderData, useSearchParams } from "@remix-run/react"; import { GetOidcRedirectUrlDocument, LatestUserSummaryDocument, @@ -31,10 +26,9 @@ import { RegisterErrorVariant, RegisterUserDocument, } from "@ryot/generated/graphql/backend/graphql"; -import { processSubmission, startCase } from "@ryot/ts-utils"; +import { getActionIntent, processSubmission, startCase } from "@ryot/ts-utils"; import { IconAt } from "@tabler/icons-react"; import { $path } from "remix-routes"; -import { namedAction } from "remix-utils/named-action"; import { safeRedirect } from "remix-utils/safe-redirect"; import { match } from "ts-pattern"; import { withQuery } from "ufo"; @@ -59,7 +53,7 @@ const searchParamsSchema = z.object({ export type SearchParams = z.infer & Record; -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const query = zx.parseQuery(request, searchParamsSchema); const isAuthenticated = !!getAuthorizationCookie(request); if (isAuthenticated) { @@ -94,16 +88,17 @@ export const loader = unstable_defineLoader(async ({ request }) => { tokenValidForDays: coreDetails.tokenValidForDays, signupAllowed: coreDetails.signupAllowed, }; -}); +}; -export const meta = (_args: MetaArgs_SingleFetch) => [ +export const meta = (_args: MetaArgs) => [ { title: "Authentication | Ryot" }, ]; -export const action = unstable_defineAction(async ({ request }) => { - const formData = await request.formData(); - return namedAction(request, { - register: async () => { +export const action = async ({ request }: ActionFunctionArgs) => { + const formData = await request.clone().formData(); + const intent = getActionIntent(request); + return await match(intent) + .with("register", async () => { const submission = parseWithZod(formData, { schema: registerSchema, }); @@ -148,8 +143,8 @@ export const action = unstable_defineAction(async ({ request }) => { type: "success", message: "Please login with your new credentials", }); - }, - login: async () => { + }) + .with("login", async () => { const submission = processSubmission(formData, loginSchema); const { loginUser } = await serverGqlService.request(LoginUserDocument, { input: { @@ -185,15 +180,15 @@ export const action = unstable_defineAction(async ({ request }) => { return Response.json({} as const, { headers: await createToastHeaders({ message, type: "error" }), }); - }, - getOidcRedirectUrl: async () => { + }) + .with("getOidcRedirectUrl", async () => { const { getOidcRedirectUrl } = await serverGqlService.request( GetOidcRedirectUrlDocument, ); return redirect(getOidcRedirectUrl); - }, - }); -}); + }) + .run(); +}; const registerSchema = z .object({ diff --git a/apps/frontend/app/styles/preferences.module.css b/apps/frontend/app/styles/preferences.module.css index dbc8384921..293324c578 100644 --- a/apps/frontend/app/styles/preferences.module.css +++ b/apps/frontend/app/styles/preferences.module.css @@ -1,3 +1,3 @@ .itemDragging { - box-shadow: var(--mantine-shadow-sm); + box-shadow: var(--mantine-shadow-sm); } diff --git a/apps/frontend/package.json b/apps/frontend/package.json index 0dd0e7c555..5f5be3dab2 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -7,56 +7,56 @@ "hoistingLimits": "workspaces" }, "dependencies": { - "@conform-to/react": "1.1.5", - "@conform-to/zod": "1.1.5", + "@conform-to/react": "1.2.2", + "@conform-to/zod": "1.2.2", "@formkit/auto-animate": "0.8.2", - "@hello-pangea/dnd": "16.6.0", + "@hello-pangea/dnd": "17.0.0", "@lukemorales/query-key-factory": "1.3.4", - "@mantine/carousel": "7.12.1", - "@mantine/charts": "7.12.1", - "@mantine/core": "7.12.1", - "@mantine/dates": "7.12.1", - "@mantine/form": "7.12.1", - "@mantine/hooks": "7.12.1", - "@mantine/notifications": "7.12.1", + "@mantine/carousel": "7.13.3", + "@mantine/charts": "7.13.3", + "@mantine/core": "7.13.3", + "@mantine/dates": "7.13.3", + "@mantine/form": "7.13.3", + "@mantine/hooks": "7.13.3", + "@mantine/notifications": "7.13.3", "@remix-pwa/sw": "3.0.10", "@remix-pwa/worker-runtime": "2.1.4", - "@remix-run/node": "2.11.2", - "@remix-run/react": "2.11.2", - "@remix-run/serve": "2.11.2", + "@remix-run/node": "2.13.1", + "@remix-run/react": "2.13.1", + "@remix-run/serve": "2.13.1", "@ryot/generated": "workspace:*", "@ryot/graphql": "workspace:*", "@ryot/ts-utils": "workspace:*", - "@tabler/icons-react": "3.12.0", - "@tanstack/react-query": "5.52.0", - "@tanstack/react-query-devtools": "5.52.0", + "@tabler/icons-react": "3.19.0", + "@tanstack/react-query": "5.59.15", + "@tanstack/react-query-devtools": "5.59.15", "buffer": "6.0.3", "clsx": "2.1.1", - "cookie": "0.6.0", + "cookie": "1.0.1", "dayjs": "1.11.13", "dotenv": "16.4.5", "embla-carousel-react": "7.1.0", - "filesize": "10.1.4", + "filesize": "10.1.6", "graphql": "16.9.0", "graphql-request": "7.1.0", "howler": "2.2.4", "humanize-duration-ts": "2.1.1", "immer": "10.1.1", "isbot": "5.1.17", - "jotai": "2.9.3", + "jotai": "2.10.1", "js-cookie": "3.0.5", "jwt-decode": "4.0.0", - "mantine-datatable": "7.11.3", + "mantine-datatable": "7.12.4", "react": "18.3.1", "react-confirm": "0.3.0-7", "react-dom": "18.3.1", - "react-virtuoso": "4.10.1", + "react-virtuoso": "4.12.0", "react-webcam": "7.2.0", - "recharts": "2.12.7", + "recharts": "2.13.0", "remix-routes": "1.7.7", - "remix-utils": "7.6.0", + "remix-utils": "7.7.0", "tiny-invariant": "1.3.3", - "ts-pattern": "5.3.1", + "ts-pattern": "5.5.0", "ufo": "1.5.4", "usehooks-ts": "3.1.0", "uuid": "10.0.0", @@ -66,23 +66,23 @@ "devDependencies": { "@bitprojects/umami-logger-typescript": "1.0.10", "@remix-pwa/dev": "3.1.0", - "@remix-run/dev": "2.11.2", + "@remix-run/dev": "2.13.1", "@types/cookie": "0.6.0", "@types/crypto-js": "4.2.2", - "@types/howler": "2.2.11", + "@types/howler": "2.2.12", "@types/js-cookie": "3.0.6", - "@types/react": "18.3.4", - "@types/react-dom": "18.3.0", + "@types/react": "18.3.11", + "@types/react-dom": "18.3.1", "@types/uuid": "10.0.0", - "postcss": "8.4.41", + "postcss": "8.4.47", "postcss-preset-mantine": "1.17.0", "postcss-simple-vars": "7.0.1", - "remix-development-tools": "4.4.1", + "remix-development-tools": "4.7.3", "ts-essentials": "10.0.2", - "typescript": "5.5.4", + "typescript": "5.6.3", "typescript-plugin-css-modules": "5.1.0", "typescript-remix-routes-plugin": "1.0.1", - "vite": "5.4.2", + "vite": "5.4.9", "vite-tsconfig-paths": "5.0.1" }, "engines": { diff --git a/apps/frontend/tsconfig.json b/apps/frontend/tsconfig.json index 78c6e97e08..72dd2478d2 100644 --- a/apps/frontend/tsconfig.json +++ b/apps/frontend/tsconfig.json @@ -31,8 +31,7 @@ { "name": "typescript-remix-routes-plugin" } - ], - "types": ["@remix-run/react/future/single-fetch.d.ts"] + ] }, "references": [ { diff --git a/apps/frontend/vite.config.ts b/apps/frontend/vite.config.ts index 9417ecf65a..004c9aa9f8 100644 --- a/apps/frontend/vite.config.ts +++ b/apps/frontend/vite.config.ts @@ -5,6 +5,12 @@ import { remixRoutes } from "remix-routes/vite"; import { defineConfig } from "vite"; import tsconfigPaths from "vite-tsconfig-paths"; +declare module "@remix-run/server-runtime" { + interface Future { + v3_singleFetch: true; + } +} + export default defineConfig({ server: { port: process.env.FRONTEND_PORT @@ -15,7 +21,7 @@ export default defineConfig({ plugins: [ remixDevTools(), remix({ - future: { unstable_singleFetch: true }, + future: { v3_singleFetch: true }, }), remixRoutes(), tsconfigPaths(), diff --git a/apps/website/app/lib/components/ui/carousel.tsx b/apps/website/app/lib/components/ui/carousel.tsx index dffc3cb36e..60c760410e 100644 --- a/apps/website/app/lib/components/ui/carousel.tsx +++ b/apps/website/app/lib/components/ui/carousel.tsx @@ -134,10 +134,9 @@ const Carousel = React.forwardRef< >
{children} diff --git a/apps/website/app/lib/components/ui/input-otp.tsx b/apps/website/app/lib/components/ui/input-otp.tsx index 9ab935b92c..2778f55fa5 100644 --- a/apps/website/app/lib/components/ui/input-otp.tsx +++ b/apps/website/app/lib/components/ui/input-otp.tsx @@ -62,7 +62,6 @@ const InputOTPSeparator = React.forwardRef< >(({ ...props }, ref) => (
{ const client = createTransport({ + secure: true, host: serverVariables.SERVER_SMTP_SERVER, auth: { user: serverVariables.SERVER_SMTP_USER, pass: serverVariables.SERVER_SMTP_PASSWORD, }, - secure: true, }); - const html = render(element, { pretty: true }); - const text = render(element, { plainText: true }); + const html = await render(element, { pretty: true }); + const text = await render(element, { plainText: true }); const resp = await client.sendMail({ - from: '"Ryot" ', - to: recipient, - subject, text, html, + subject, + to: recipient, + from: '"Ryot" ', }); return resp.messageId; }; diff --git a/apps/website/app/root.tsx b/apps/website/app/root.tsx index ecdac9ce54..97444c2bb0 100644 --- a/apps/website/app/root.tsx +++ b/apps/website/app/root.tsx @@ -9,11 +9,10 @@ import { } from "@remix-run/react"; import { HoneypotProvider } from "remix-utils/honeypot/react"; import "./tailwind.css"; -import { - type LinksFunction, - type MetaFunction, - json, - unstable_defineLoader, +import type { + LinksFunction, + LoaderFunctionArgs, + MetaFunction, } from "@remix-run/node"; import { $path } from "remix-routes"; import { withFragment } from "ufo"; @@ -41,13 +40,13 @@ export const links: LinksFunction = () => { ]; }; -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const userId = await getUserIdFromCookie(request); - return json({ + return { isLoggedIn: !!userId, honeypotInputProps: honeypot.getInputProps(), - }); -}); + }; +}; export const meta: MetaFunction = () => { return [{ title: "Ryot" }]; diff --git a/apps/website/app/routes/_index.tsx b/apps/website/app/routes/_index.tsx index dbcbd04acc..7e8df9cb38 100644 --- a/apps/website/app/routes/_index.tsx +++ b/apps/website/app/routes/_index.tsx @@ -1,12 +1,16 @@ import TTLCache from "@isaacs/ttlcache"; import { + type ActionFunctionArgs, + type LoaderFunctionArgs, redirect, - unstable_defineAction, - unstable_defineLoader, } from "@remix-run/node"; import { Form, Link, useLoaderData } from "@remix-run/react"; import LoginCodeEmail from "@ryot/transactional/emails/LoginCode"; -import { processSubmission, randomString } from "@ryot/ts-utils"; +import { + getActionIntent, + processSubmission, + randomString, +} from "@ryot/ts-utils"; import { IconBrandDiscord, IconBrandGithub, @@ -20,7 +24,7 @@ import { REGEXP_ONLY_DIGITS_AND_CHARS } from "input-otp"; import { $path } from "remix-routes"; import { HoneypotInputs } from "remix-utils/honeypot/react"; import { SpamError } from "remix-utils/honeypot/server"; -import { namedAction } from "remix-utils/named-action"; +import { match } from "ts-pattern"; import { withFragment, withQuery } from "ufo"; import { z } from "zod"; import { zx } from "zodix"; @@ -61,21 +65,22 @@ const searchParamsSchema = z.object({ export type SearchParams = z.infer; -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const query = zx.parseQuery(request, searchParamsSchema); const userId = await getUserIdFromCookie(request); return { prices, query, isLoggedIn: !!userId }; -}); +}; const otpCodesCache = new TTLCache({ ttl: dayjs.duration(5, "minutes").asMilliseconds(), max: 1000, }); -export const action = unstable_defineAction(async ({ request }) => { +export const action = async ({ request }: ActionFunctionArgs) => { const formData = await request.clone().formData(); - return await namedAction(request, { - sendLoginCode: async () => { + const intent = getActionIntent(request); + return await match(intent) + .with("sendLoginCode", async () => { const { email } = processSubmission(formData, emailSchema); const otpCode = randomString(6); otpCodesCache.set(email, otpCode); @@ -86,8 +91,8 @@ export const action = unstable_defineAction(async ({ request }) => { LoginCodeEmail({ code: otpCode }), ); return redirect(withQuery(withFragment(".", "start-here"), { email })); - }, - registerWithEmail: async () => { + }) + .with("registerWithEmail", async () => { const submission = processSubmission(formData, registerSchema); const otpCode = otpCodesCache.get(submission.email); if (otpCode !== submission.otpCode) throw new Error("Invalid OTP code."); @@ -105,13 +110,13 @@ export const action = unstable_defineAction(async ({ request }) => { return redirect($path("/me"), { headers: { "set-cookie": await authCookie.serialize(customerId) }, }); - }, - registerWithOidc: async () => { + }) + .with("registerWithOidc", async () => { const client = await oauthClient(); const redirectUrl = client.authorizationUrl({ scope: "openid email" }); return redirect(redirectUrl); - }, - contactSubmission: async () => { + }) + .with("contactSubmission", async () => { let isSpam = false; try { honeypot.check(formData); @@ -130,9 +135,9 @@ export const action = unstable_defineAction(async ({ request }) => { return redirect( withQuery(withFragment(".", "contact"), { contactSubmission: true }), ); - }, - }); -}); + }) + .run(); +}; const intentSchema = z.object({ intent: z.string() }); @@ -294,17 +299,15 @@ export default function Page() { ) : ( <> - - + {loaderData.query.email ? ( <>

OR

-
- +
diff --git a/apps/website/app/routes/callback.tsx b/apps/website/app/routes/callback.tsx index 6298bf5b0b..6b00293353 100644 --- a/apps/website/app/routes/callback.tsx +++ b/apps/website/app/routes/callback.tsx @@ -1,4 +1,4 @@ -import { redirect, unstable_defineLoader } from "@remix-run/node"; +import { type LoaderFunctionArgs, redirect } from "@remix-run/node"; import { eq } from "drizzle-orm"; import { $path } from "remix-routes"; import { match } from "ts-pattern"; @@ -10,7 +10,7 @@ import { oauthClient, } from "~/lib/config.server"; -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const client = await oauthClient(); const params = client.callbackParams(request.url); const tokenSet = await client.callback(OAUTH_CALLBACK_URL, params, { @@ -39,4 +39,4 @@ export const loader = unstable_defineLoader(async ({ request }) => { return redirect($path("/me"), { headers: { "set-cookie": await authCookie.serialize(customerId) }, }); -}); +}; diff --git a/apps/website/app/routes/me.tsx b/apps/website/app/routes/me.tsx index c5196241c8..864161dfeb 100644 --- a/apps/website/app/routes/me.tsx +++ b/apps/website/app/routes/me.tsx @@ -3,17 +3,16 @@ import { type Paddle, initializePaddle, } from "@paddle/paddle-js"; -import { unstable_defineAction, unstable_defineLoader } from "@remix-run/node"; +import type { ActionFunctionArgs, LoaderFunctionArgs } from "@remix-run/node"; import { Form, redirect, useLoaderData, useSubmit } from "@remix-run/react"; import { RegisterUserDocument } from "@ryot/generated/graphql/backend/graphql"; import PurchaseCompleteEmail from "@ryot/transactional/emails/PurchaseComplete"; -import { changeCase, randomString } from "@ryot/ts-utils"; +import { changeCase, getActionIntent, randomString } from "@ryot/ts-utils"; import { Unkey } from "@unkey/api"; import dayjs from "dayjs"; import { eq } from "drizzle-orm"; import { useEffect, useState } from "react"; import { $path } from "remix-routes"; -import { namedAction } from "remix-utils/named-action"; import { P, match } from "ts-pattern"; import { withFragment, withQuery } from "ufo"; import { customers } from "~/drizzle/schema.server"; @@ -34,7 +33,7 @@ import { serverVariables, } from "~/lib/config.server"; -export const loader = unstable_defineLoader(async ({ request }) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const userId = await getUserIdFromCookie(request); const isLoggedIn = !!userId; if (!isLoggedIn) return redirect(withFragment($path("/"), "start-here")); @@ -61,15 +60,16 @@ export const loader = unstable_defineLoader(async ({ request }) => { isSandbox: !!serverVariables.PADDLE_SANDBOX, clientToken: serverVariables.PADDLE_CLIENT_TOKEN, }; -}); +}; -export const action = unstable_defineAction(async ({ request }) => { - return await namedAction(request.clone(), { - logout: async () => { +export const action = async ({ request }: ActionFunctionArgs) => { + const intent = getActionIntent(request); + return await match(intent) + .with("logout", async () => { const cookies = await authCookie.serialize("", { expires: new Date(0) }); return Response.json({}, { headers: { "set-cookie": cookies } }); - }, - processPurchase: async () => { + }) + .with("processPurchase", async () => { const userId = await getUserIdFromCookie(request); if (!userId) throw new Error("You must be logged in to buy a subscription"); @@ -161,9 +161,9 @@ export const action = unstable_defineAction(async ({ request }) => { }) .where(eq(customers.id, userId)); return Response.json({}); - }, - }); -}); + }) + .run(); +}; export default function Index() { const loaderData = useLoaderData(); @@ -183,7 +183,7 @@ export default function Index() { { method: "POST", encType: "application/json", - action: withQuery("?index", { intent: "processPurchase" }), + action: withQuery(".", { intent: "processPurchase" }), }, ); } @@ -256,9 +256,9 @@ export default function Index() { )}
-
diff --git a/apps/website/app/tailwind.css b/apps/website/app/tailwind.css index d6356b63a6..cbd092db62 100644 --- a/apps/website/app/tailwind.css +++ b/apps/website/app/tailwind.css @@ -3,70 +3,75 @@ @tailwind utilities; @layer base { - :root { - --background: 0 0% 100%; - --foreground: 240 10% 3.9%; - --card: 0 0% 100%; - --card-foreground: 240 10% 3.9%; - --popover: 0 0% 100%; - --popover-foreground: 240 10% 3.9%; - --primary: 240 5.9% 10%; - --primary-foreground: 0 0% 98%; - --secondary: 240 4.8% 95.9%; - --secondary-foreground: 240 5.9% 10%; - --muted: 240 4.8% 95.9%; - --muted-foreground: 240 3.8% 46.1%; - --accent: 240 4.8% 95.9%; - --accent-foreground: 240 5.9% 10%; - --destructive: 0 84.2% 60.2%; - --destructive-foreground: 0 0% 98%; - --border: 240 5.9% 90%; - --input: 240 5.9% 90%; - --ring: 240 10% 3.9%; - --radius: 0.5rem; - --chart-1: 12 76% 61%; - --chart-2: 173 58% 39%; - --chart-3: 197 37% 24%; - --chart-4: 43 74% 66%; - --chart-5: 27 87% 67%; - } + :root { + --background: 0 0% 100%; + --foreground: 240 10% 3.9%; + --card: 0 0% 100%; + --card-foreground: 240 10% 3.9%; + --popover: 0 0% 100%; + --popover-foreground: 240 10% 3.9%; + --primary: 240 5.9% 10%; + --primary-foreground: 0 0% 98%; + --secondary: 240 4.8% 95.9%; + --secondary-foreground: 240 5.9% 10%; + --muted: 240 4.8% 95.9%; + --muted-foreground: 240 3.8% 46.1%; + --accent: 240 4.8% 95.9%; + --accent-foreground: 240 5.9% 10%; + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 0 0% 98%; + --border: 240 5.9% 90%; + --input: 240 5.9% 90%; + --ring: 240 10% 3.9%; + --radius: 0.5rem; + --chart-1: 12 76% 61%; + --chart-2: 173 58% 39%; + --chart-3: 197 37% 24%; + --chart-4: 43 74% 66%; + --chart-5: 27 87% 67%; + } - .dark { - --background: 240 10% 3.9%; - --foreground: 0 0% 98%; - --card: 240 10% 3.9%; - --card-foreground: 0 0% 98%; - --popover: 240 10% 3.9%; - --popover-foreground: 0 0% 98%; - --primary: 0 0% 98%; - --primary-foreground: 240 5.9% 10%; - --secondary: 240 3.7% 15.9%; - --secondary-foreground: 0 0% 98%; - --muted: 240 3.7% 15.9%; - --muted-foreground: 240 5% 64.9%; - --accent: 240 3.7% 15.9%; - --accent-foreground: 0 0% 98%; - --destructive: 0 62.8% 30.6%; - --destructive-foreground: 0 0% 98%; - --border: 240 3.7% 15.9%; - --input: 240 3.7% 15.9%; - --ring: 240 4.9% 83.9%; - --chart-1: 220 70% 50%; - --chart-2: 160 60% 45%; - --chart-3: 30 80% 55%; - --chart-4: 280 65% 60%; - --chart-5: 340 75% 55%; - } + .dark { + --background: 240 10% 3.9%; + --foreground: 0 0% 98%; + --card: 240 10% 3.9%; + --card-foreground: 0 0% 98%; + --popover: 240 10% 3.9%; + --popover-foreground: 0 0% 98%; + --primary: 0 0% 98%; + --primary-foreground: 240 5.9% 10%; + --secondary: 240 3.7% 15.9%; + --secondary-foreground: 0 0% 98%; + --muted: 240 3.7% 15.9%; + --muted-foreground: 240 5% 64.9%; + --accent: 240 3.7% 15.9%; + --accent-foreground: 0 0% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 0% 98%; + --border: 240 3.7% 15.9%; + --input: 240 3.7% 15.9%; + --ring: 240 4.9% 83.9%; + --chart-1: 220 70% 50%; + --chart-2: 160 60% 45%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-5: 340 75% 55%; + } } @layer base { - * { - @apply border-border; - } - body { - @apply bg-background text-foreground font-body; - } - h1, h2, h3, h4, h5, h6 { - @apply font-heading; - } + * { + @apply border-border; + } + body { + @apply bg-background text-foreground font-body; + } + h1, + h2, + h3, + h4, + h5, + h6 { + @apply font-heading; + } } diff --git a/apps/website/package.json b/apps/website/package.json index 8c96636c1d..b62f0aa14c 100644 --- a/apps/website/package.json +++ b/apps/website/package.json @@ -7,69 +7,69 @@ "hoistingLimits": "workspaces" }, "dependencies": { - "@conform-to/zod": "1.1.5", + "@conform-to/zod": "1.2.2", "@isaacs/ttlcache": "1.4.1", - "@paddle/paddle-js": "1.2.0", - "@paddle/paddle-node-sdk": "1.4.1", + "@paddle/paddle-js": "1.2.3", + "@paddle/paddle-node-sdk": "1.9.1", "@radix-ui/react-label": "2.1.0", "@radix-ui/react-slot": "1.1.0", - "@radix-ui/react-tooltip": "1.1.2", - "@react-email/components": "0.0.22", - "@remix-run/node": "2.10.3", - "@remix-run/react": "2.10.3", - "@remix-run/serve": "2.10.3", + "@radix-ui/react-tooltip": "1.1.3", + "@react-email/components": "0.0.25", + "@remix-run/node": "2.13.1", + "@remix-run/react": "2.13.1", + "@remix-run/serve": "2.13.1", "@ryot/generated": "workspace:*", "@ryot/graphql": "workspace:*", "@ryot/transactional": "workspace:*", "@ryot/ts-utils": "workspace:*", - "@tabler/icons-react": "3.11.0", - "@unkey/api": "0.23.0", + "@tabler/icons-react": "3.19.0", + "@unkey/api": "0.26.2", "class-variance-authority": "0.7.0", "clsx": "2.1.1", "crypto-js": "4.2.0", - "dayjs": "1.11.12", - "drizzle-orm": "0.32.1", - "embla-carousel-autoplay": "8.1.7", - "embla-carousel-react": "8.1.7", + "dayjs": "1.11.13", + "drizzle-orm": "0.35.3", + "embla-carousel-autoplay": "8.3.0", + "embla-carousel-react": "8.3.0", "graphql": "16.9.0", "graphql-request": "7.1.0", "humanize-duration-ts": "2.1.1", "input-otp": "1.2.4", - "isbot": "4.1.0", + "isbot": "5.1.17", "lodash": "4.17.21", - "lucide-react": "0.414.0", + "lucide-react": "0.453.0", "next-themes": "0.3.0", - "nodemailer": "6.9.14", + "nodemailer": "6.9.15", "openid-client": "5.6.5", "postgres": "3.4.4", - "react": "18.2.0", - "react-dom": "18.2.0", - "remix-routes": "1.7.6", - "remix-utils": "7.6.0", + "react": "18.3.1", + "react-dom": "18.3.1", + "remix-routes": "1.7.7", + "remix-utils": "7.7.0", "sonner": "1.5.0", - "tailwind-merge": "2.4.0", + "tailwind-merge": "2.5.4", "tailwindcss-animate": "1.0.7", - "ts-pattern": "5.2.0", + "ts-pattern": "5.5.0", "ufo": "1.5.4", "zod": "3.23.8", "zodix": "0.4.4" }, "devDependencies": { - "@remix-run/dev": "2.10.3", - "@tailwindcss/typography": "0.5.13", - "@types/crypto-js": "^4", - "@types/lodash": "4.17.7", - "@types/nodemailer": "6", - "@types/react": "18.2.20", - "@types/react-dom": "18.2.7", - "autoprefixer": "10.4.19", - "drizzle-kit": "0.23.0", - "postcss": "8.4.38", - "tailwindcss": "3.4.4", - "typescript": "5.1.6", + "@remix-run/dev": "2.13.1", + "@tailwindcss/typography": "0.5.15", + "@types/crypto-js": "^4.2.2", + "@types/lodash": "4.17.12", + "@types/nodemailer": "6.4.16", + "@types/react": "18.3.11", + "@types/react-dom": "18.3.1", + "autoprefixer": "10.4.20", + "drizzle-kit": "0.26.2", + "postcss": "8.4.47", + "tailwindcss": "3.4.14", + "typescript": "5.6.3", "typescript-remix-routes-plugin": "1.0.1", - "vite": "5.1.0", - "vite-tsconfig-paths": "4.2.1" + "vite": "5.4.9", + "vite-tsconfig-paths": "5.0.1" }, "engines": { "node": ">=20.0.0" diff --git a/apps/website/vite.config.ts b/apps/website/vite.config.ts index 1180757683..b00785e4fe 100644 --- a/apps/website/vite.config.ts +++ b/apps/website/vite.config.ts @@ -3,14 +3,20 @@ import { remixRoutes } from "remix-routes/vite"; import { defineConfig } from "vite"; import tsconfigPaths from "vite-tsconfig-paths"; +declare module "@remix-run/server-runtime" { + interface Future { + v3_singleFetch: true; + } +} + export default defineConfig({ plugins: [ remix({ future: { - unstable_singleFetch: true, + v3_singleFetch: true, v3_fetcherPersist: true, - v3_relativeSplatPath: true, v3_throwAbortReason: true, + v3_relativeSplatPath: true, }, }), remixRoutes(), diff --git a/crates/background/Cargo.toml b/crates/background/Cargo.toml index 858b994826..03a49d4361 100644 --- a/crates/background/Cargo.toml +++ b/crates/background/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" apalis = { workspace = true } chrono = { workspace = true } chrono-tz = { workspace = true } +database-models = { path = "../models/database" } enums = { path = "../enums" } fitness-models = { path = "../models/fitness" } media-models = { path = "../models/media" } diff --git a/crates/background/src/lib.rs b/crates/background/src/lib.rs index a97203d983..3b0cdb57dc 100644 --- a/crates/background/src/lib.rs +++ b/crates/background/src/lib.rs @@ -1,6 +1,7 @@ use apalis::prelude::{Job, Message}; use chrono::DateTime; use chrono_tz::Tz; +use database_models::seen; use enums::{MediaLot, MediaSource}; use fitness_models::GithubExercise; use media_models::{DeployImportJobInput, ProgressUpdateInput, ReviewPostedEvent}; @@ -37,6 +38,8 @@ pub enum ApplicationJob { UpdateExerciseLibrary, SyncIntegrationsData, HandleEntityAddedToCollectionEvent(Uuid), + HandleAfterMediaSeenTasks(seen::Model), + HandleOnSeenComplete(String), } impl Message for ApplicationJob { diff --git a/crates/enums/src/lib.rs b/crates/enums/src/lib.rs index a118a35211..fead503a2a 100644 --- a/crates/enums/src/lib.rs +++ b/crates/enums/src/lib.rs @@ -454,12 +454,13 @@ pub enum IntegrationLot { #[serde(rename_all = "snake_case")] pub enum IntegrationProvider { Audiobookshelf, - Jellyfin, + JellyfinSink, Emby, Plex, Kodi, Radarr, Sonarr, + JellyfinPush, Komga, GenericJson, } diff --git a/crates/migrations/src/lib.rs b/crates/migrations/src/lib.rs index fd2da26dae..a2605fafae 100644 --- a/crates/migrations/src/lib.rs +++ b/crates/migrations/src/lib.rs @@ -45,6 +45,7 @@ mod m20241006_changes_for_issue_1056; mod m20241010_changes_for_issue_708; mod m20241013_changes_for_issue_1052; mod m20241019_changes_for_issue_929; +mod m20241019_changes_for_issue_964; pub use m20230410_create_metadata::Metadata as AliasedMetadata; pub use m20230413_create_person::Person as AliasedPerson; @@ -110,6 +111,7 @@ impl MigratorTrait for Migrator { Box::new(m20241010_changes_for_issue_708::Migration), Box::new(m20241013_changes_for_issue_1052::Migration), Box::new(m20241019_changes_for_issue_929::Migration), + Box::new(m20241019_changes_for_issue_964::Migration), ] } } diff --git a/crates/migrations/src/m20240827_create_daily_user_activity.rs b/crates/migrations/src/m20240827_create_daily_user_activity.rs index e3610cfd5b..0d0f9c4142 100644 --- a/crates/migrations/src/m20240827_create_daily_user_activity.rs +++ b/crates/migrations/src/m20240827_create_daily_user_activity.rs @@ -39,6 +39,7 @@ pub enum DailyUserActivity { ShowCount, ShowDuration, VideoGameCount, + VideoGameDuration, VisualNovelCount, VisualNovelDuration, WorkoutPersonalBests, @@ -96,6 +97,7 @@ impl MigrationTrait for Migration { .col(integer_not_null(DailyUserActivity::ShowCount)) .col(integer_not_null(DailyUserActivity::ShowDuration)) .col(integer_not_null(DailyUserActivity::VideoGameCount)) + .col(integer_not_null(DailyUserActivity::VideoGameDuration)) .col(integer_not_null(DailyUserActivity::VisualNovelCount)) .col(integer_not_null(DailyUserActivity::VisualNovelDuration)) .col(integer_not_null(DailyUserActivity::WorkoutPersonalBests)) diff --git a/crates/migrations/src/m20241019_changes_for_issue_964.rs b/crates/migrations/src/m20241019_changes_for_issue_964.rs new file mode 100644 index 0000000000..a1da3a8448 --- /dev/null +++ b/crates/migrations/src/m20241019_changes_for_issue_964.rs @@ -0,0 +1,23 @@ +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + let db = manager.get_connection(); + db.execute_unprepared( + r#" +UPDATE "integration" SET "provider" = 'jellyfin_sink' WHERE "provider" = 'jellyfin'; +ALTER TABLE "daily_user_activity" ADD COLUMN IF NOT EXISTS "video_game_duration" INTEGER NOT NULL DEFAULT 0; + "#, + ) + .await?; + Ok(()) + } + + async fn down(&self, _manager: &SchemaManager) -> Result<(), DbErr> { + Ok(()) + } +} diff --git a/crates/models/database/src/daily_user_activity.rs b/crates/models/database/src/daily_user_activity.rs index dad603d890..73fdd5c14c 100644 --- a/crates/models/database/src/daily_user_activity.rs +++ b/crates/models/database/src/daily_user_activity.rs @@ -32,6 +32,7 @@ pub struct Model { pub show_count: i32, pub show_duration: i32, pub video_game_count: i32, + pub video_game_duration: i32, pub visual_novel_count: i32, pub visual_novel_duration: i32, pub workout_personal_bests: i32, diff --git a/crates/models/media/src/lib.rs b/crates/models/media/src/lib.rs index d40dec8425..fb319a47f8 100644 --- a/crates/models/media/src/lib.rs +++ b/crates/models/media/src/lib.rs @@ -931,22 +931,30 @@ pub struct PersonStateChanges { #[serde(rename_all = "snake_case")] pub struct IntegrationProviderSpecifics { pub plex_username: Option, + pub audiobookshelf_base_url: Option, pub audiobookshelf_token: Option, + pub komga_base_url: Option, pub komga_username: Option, pub komga_password: Option, pub komga_provider: Option, + pub radarr_base_url: Option, pub radarr_api_key: Option, pub radarr_profile_id: Option, pub radarr_root_folder_path: Option, pub radarr_sync_collection_ids: Option>, + pub sonarr_base_url: Option, pub sonarr_api_key: Option, pub sonarr_profile_id: Option, pub sonarr_root_folder_path: Option, pub sonarr_sync_collection_ids: Option>, + + pub jellyfin_push_base_url: Option, + pub jellyfin_push_username: Option, + pub jellyfin_push_password: Option, } #[derive(Debug, Clone, Serialize, Deserialize, SimpleObject)] @@ -1625,6 +1633,7 @@ pub struct DailyUserActivityItem { pub show_count: i64, pub total_show_duration: i64, pub video_game_count: i64, + pub total_video_game_duration: i64, pub visual_novel_count: i64, pub total_visual_novel_duration: i64, pub total_workout_personal_bests: i64, diff --git a/crates/services/exporter/Cargo.toml b/crates/services/exporter/Cargo.toml index cf67ce8c4e..1d212e3daa 100644 --- a/crates/services/exporter/Cargo.toml +++ b/crates/services/exporter/Cargo.toml @@ -4,7 +4,6 @@ version = "0.1.0" edition = "2021" [dependencies] -apalis = { workspace = true } async-graphql = { workspace = true } background = { path = "../../background" } chrono = { workspace = true } diff --git a/crates/services/exporter/src/lib.rs b/crates/services/exporter/src/lib.rs index 2ac943aae4..52d1606c22 100644 --- a/crates/services/exporter/src/lib.rs +++ b/crates/services/exporter/src/lib.rs @@ -1,6 +1,5 @@ use std::{collections::HashMap, fs::File as StdFile, path::PathBuf, sync::Arc}; -use apalis::prelude::MessageQueue; use async_graphql::{Error, Result}; use background::ApplicationJob; use chrono::{DateTime, Utc}; @@ -55,11 +54,8 @@ pub struct ExporterService(pub Arc); impl ExporterService { pub async fn deploy_export_job(&self, user_id: String) -> Result { self.0 - .perform_application_job - .clone() - .enqueue(ApplicationJob::PerformExport(user_id)) - .await - .unwrap(); + .perform_application_job(ApplicationJob::PerformExport(user_id)) + .await?; Ok(true) } diff --git a/crates/services/fitness/Cargo.toml b/crates/services/fitness/Cargo.toml index 4d6341b732..7ee7bda38e 100644 --- a/crates/services/fitness/Cargo.toml +++ b/crates/services/fitness/Cargo.toml @@ -4,7 +4,6 @@ version = "0.1.0" edition = "2021" [dependencies] -apalis = { workspace = true } application-utils = { path = "../../utils/application" } async-graphql = { workspace = true } background = { path = "../../background" } diff --git a/crates/services/fitness/src/lib.rs b/crates/services/fitness/src/lib.rs index 35b1efdc22..624cb285f1 100644 --- a/crates/services/fitness/src/lib.rs +++ b/crates/services/fitness/src/lib.rs @@ -1,6 +1,5 @@ use std::sync::Arc; -use apalis::prelude::MessageQueue; use application_utils::GraphqlRepresentation; use async_graphql::{Error, Result}; use background::ApplicationJob; @@ -437,11 +436,8 @@ impl ExerciseService { let exercises = self.get_all_exercises_from_dataset().await?; for exercise in exercises { self.0 - .perform_application_job - .clone() - .enqueue(ApplicationJob::UpdateGithubExerciseJob(exercise)) - .await - .unwrap(); + .perform_application_job(ApplicationJob::UpdateGithubExerciseJob(exercise)) + .await?; } Ok(true) } @@ -569,8 +565,7 @@ impl ExerciseService { } if new_wkt.is_changed() { new_wkt.update(&self.0.db).await?; - deploy_job_to_re_evaluate_user_workouts(&user_id, &self.0.perform_application_job) - .await; + deploy_job_to_re_evaluate_user_workouts(&user_id, &self.0).await; Ok(true) } else { Ok(false) @@ -660,11 +655,8 @@ impl ExerciseService { } wkt.delete(&self.0.db).await?; self.0 - .perform_application_job - .clone() - .enqueue(ApplicationJob::ReEvaluateUserWorkouts(user_id)) - .await - .ok(); + .perform_application_job(ApplicationJob::ReEvaluateUserWorkouts(user_id)) + .await?; Ok(true) } diff --git a/crates/services/importer/Cargo.toml b/crates/services/importer/Cargo.toml index a03ca9cb91..af3759a665 100644 --- a/crates/services/importer/Cargo.toml +++ b/crates/services/importer/Cargo.toml @@ -5,7 +5,6 @@ edition = "2021" [dependencies] anyhow = { workspace = true } -apalis = { workspace = true } application-utils = { path = "../../utils/application" } async-graphql = { workspace = true } background = { path = "../../background" } @@ -16,6 +15,7 @@ csv = "=1.3.0" data-encoding = "=2.6.0" enum_meta = { workspace = true } env-utils = { path = "../../utils/env" } +external-utils = { path = "../../utils/external" } common-models = { path = "../../models/common" } common-utils = { path = "../../utils/common" } database-models = { path = "../../models/database" } diff --git a/crates/services/importer/src/jellyfin.rs b/crates/services/importer/src/jellyfin.rs index d949d8b5e7..6889398e45 100644 --- a/crates/services/importer/src/jellyfin.rs +++ b/crates/services/importer/src/jellyfin.rs @@ -1,114 +1,27 @@ use async_graphql::Result; -use common_utils::{ryot_log, APPLICATION_JSON_HEADER, USER_AGENT_STR}; +use common_utils::ryot_log; use dependent_models::ImportResult; use enum_meta::HashMap; use enums::{MediaLot, MediaSource}; +use external_utils::jellyfin::{get_authenticated_client, ItemResponse, ItemsResponse, MediaType}; use media_models::{ DeployUrlAndKeyAndUsernameImportInput, ImportOrExportMediaItem, ImportOrExportMediaItemSeen, }; -use reqwest::{ - header::{HeaderMap, HeaderValue, ACCEPT, AUTHORIZATION, USER_AGENT}, - Client, ClientBuilder, -}; -use sea_orm::prelude::DateTimeUtc; -use serde::{Deserialize, Serialize}; use serde_json::json; use super::{ImportFailStep, ImportFailedItem}; -static EMBY_HEADER_VALUE: &str = - r#"MediaBrowser , Client="other", Device="script", DeviceId="script", Version="0.0.0""#; - -#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)] -enum MediaType { - Movie, - Series, - Episode, - #[serde(untagged)] - Unknown(String), -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(rename_all = "PascalCase")] -struct ItemProviderIdsPayload { - tmdb: Option, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(rename_all = "PascalCase")] -struct ItemUserData { - last_played_date: Option, - is_favorite: Option, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(rename_all = "PascalCase")] -struct ItemResponse { - id: String, - name: String, - #[serde(rename = "Type")] - type_: Option, - index_number: Option, - series_id: Option, - series_name: Option, - user_data: Option, - parent_index_number: Option, - provider_ids: Option, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(rename_all = "PascalCase")] -struct ItemsResponse { - items: Vec, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(rename_all = "PascalCase")] -struct AuthenticateResponse { - user: ItemResponse, - access_token: String, -} - pub async fn import(input: DeployUrlAndKeyAndUsernameImportInput) -> Result { - let uri = format!("{}/Users/AuthenticateByName", input.api_url); - let client = Client::new(); - let authenticate = client - .post(uri) - .header(AUTHORIZATION, EMBY_HEADER_VALUE) - .json(&serde_json::json!({ "Username": input.username, "Pw": input.password })) - .send() - .await - .unwrap() - .json::() - .await - .unwrap(); - ryot_log!( - debug, - "Authenticated with token: {}", - authenticate.access_token - ); - - let mut headers = HeaderMap::new(); - headers.insert(USER_AGENT, HeaderValue::from_static(USER_AGENT_STR)); - headers.insert(ACCEPT, APPLICATION_JSON_HEADER.clone()); - headers.insert( - "X-Emby-Token", - HeaderValue::from_str(&authenticate.access_token).unwrap(), - ); - let url = input.api_url; - let client: Client = ClientBuilder::new() - .default_headers(headers) - .build() - .unwrap(); - let user_id = authenticate.user.id; - ryot_log!(debug, "Authenticated as user id: {}", user_id); - let mut to_handle_media = vec![]; let mut failed_items = vec![]; + let base_url = input.api_url; + let (client, user_id) = + get_authenticated_client(&base_url, &input.username, &input.password).await?; + let query = json!({ "recursive": true, "IsPlayed": true, "fields": "ProviderIds" }); let library_data = client - .get(&format!("{}/Users/{}/Items", url, user_id)) + .get(&format!("{}/Users/{}/Items", base_url, user_id)) .query(&query) .send() .await @@ -129,7 +42,7 @@ pub async fn import(input: DeployUrlAndKeyAndUsernameImportInput) -> Result Result { let job = ApplicationJob::ImportFromExternalSource(user_id, Box::new(input)); - self.0 - .perform_application_job - .clone() - .enqueue(job) - .await - .unwrap(); + self.0.perform_application_job(job).await?; ryot_log!(debug, "Deployed import job"); Ok(true) } diff --git a/crates/services/integration/Cargo.toml b/crates/services/integration/Cargo.toml index 6e2906c7fd..664d0a35ea 100644 --- a/crates/services/integration/Cargo.toml +++ b/crates/services/integration/Cargo.toml @@ -16,6 +16,7 @@ dependent-models = { path = "../../models/dependent" } dependent-utils = { path = "../../utils/dependent" } enums = { path = "../../enums" } eventsource-stream = "=0.2.3" +external-utils = { path = "../../utils/external" } itertools = { workspace = true } media-models = { path = "../../models/media" } providers = { path = "../../providers" } diff --git a/crates/services/integration/src/lib.rs b/crates/services/integration/src/lib.rs index 5277aad9bf..8f7abf5121 100644 --- a/crates/services/integration/src/lib.rs +++ b/crates/services/integration/src/lib.rs @@ -4,18 +4,20 @@ use async_graphql::{Error, Result as GqlResult}; use chrono::Utc; use common_utils::ryot_log; use database_models::{ - integration, - prelude::{CollectionToEntity, Integration, Metadata, UserToEntity}, - user_to_entity, + integration, metadata, + prelude::{CollectionToEntity, Integration, Metadata, Seen, UserToEntity}, + seen, user_to_entity, }; use database_utils::user_preferences_by_id; use dependent_models::ImportResult; use dependent_utils::{commit_metadata, process_import}; use enums::{EntityLot, IntegrationLot, IntegrationProvider, MediaLot}; +use media_models::SeenShowExtraInformation; use providers::google_books::GoogleBooksService; +use push::jellyfin::JellyfinPushIntegration; use rust_decimal_macros::dec; use sea_orm::{ActiveModelTrait, ActiveValue, ColumnTrait, EntityTrait, QueryFilter, QuerySelect}; -use sink::generic_json::GenericJsonIntegration; +use sink::generic_json::GenericJsonSinkIntegration; use supporting_service::SupportingService; use traits::TraceOk; use uuid::Uuid; @@ -26,12 +28,12 @@ mod utils; mod yank; use crate::{ - push::{radarr::RadarrIntegration, sonarr::SonarrIntegration}, + push::{radarr::RadarrPushIntegration, sonarr::SonarrPushIntegration}, sink::{ - emby::EmbyIntegration, jellyfin::JellyfinIntegration, kodi::KodiIntegration, - plex::PlexIntegration, + emby::EmbySinkIntegration, jellyfin::JellyfinSinkIntegration, kodi::KodiSinkIntegration, + plex::PlexSinkIntegration, }, - yank::{audiobookshelf::AudiobookshelfIntegration, komga::KomgaIntegration}, + yank::{audiobookshelf::AudiobookshelfYankIntegration, komga::KomgaYankIntegration}, }; pub struct IntegrationService(pub Arc); @@ -101,25 +103,25 @@ impl IntegrationService { } let maybe_progress_update = match integration.provider { IntegrationProvider::Kodi => { - let kodi = KodiIntegration::new(payload); + let kodi = KodiSinkIntegration::new(payload); kodi.yank_progress().await } IntegrationProvider::Emby => { - let emby = EmbyIntegration::new(payload, self.0.db.clone()); + let emby = EmbySinkIntegration::new(payload, self.0.db.clone()); emby.yank_progress().await } - IntegrationProvider::Jellyfin => { - let jellyfin = JellyfinIntegration::new(payload); + IntegrationProvider::JellyfinSink => { + let jellyfin = JellyfinSinkIntegration::new(payload); jellyfin.yank_progress().await } IntegrationProvider::Plex => { let specifics = integration.clone().provider_specifics.unwrap(); let plex = - PlexIntegration::new(payload, specifics.plex_username, self.0.db.clone()); + PlexSinkIntegration::new(payload, specifics.plex_username, self.0.db.clone()); plex.yank_progress().await } IntegrationProvider::GenericJson => { - let generic_json = GenericJsonIntegration::new(payload); + let generic_json = GenericJsonSinkIntegration::new(payload); generic_json.yank_progress().await } _ => return Err(Error::new("Unsupported integration source".to_owned())), @@ -189,7 +191,7 @@ impl IntegrationService { if let Some(entity_id) = maybe_entity_id { let _push_result = match integration.provider { IntegrationProvider::Radarr => { - let radarr = RadarrIntegration::new( + let radarr = RadarrPushIntegration::new( specifics.radarr_base_url.unwrap(), specifics.radarr_api_key.unwrap(), specifics.radarr_profile_id.unwrap(), @@ -199,7 +201,7 @@ impl IntegrationService { radarr.push_progress().await } IntegrationProvider::Sonarr => { - let sonarr = SonarrIntegration::new( + let sonarr = SonarrPushIntegration::new( specifics.sonarr_base_url.unwrap(), specifics.sonarr_api_key.unwrap(), specifics.sonarr_profile_id.unwrap(), @@ -216,6 +218,41 @@ impl IntegrationService { Ok(()) } + pub async fn handle_on_seen_complete(&self, id: String) -> GqlResult<()> { + let (seen, show_extra_information, metadata_title) = Seen::find_by_id(id) + .left_join(Metadata) + .select_only() + .columns([seen::Column::UserId, seen::Column::ShowExtraInformation]) + .columns([metadata::Column::Title]) + .into_tuple::<(String, Option, String)>() + .one(&self.0.db) + .await? + .ok_or_else(|| Error::new("Seen with the given ID could not be found"))?; + let integrations = Integration::find() + .filter(integration::Column::UserId.eq(seen)) + .filter(integration::Column::Lot.eq(IntegrationLot::Push)) + .filter(integration::Column::Provider.eq(IntegrationProvider::JellyfinPush)) + .all(&self.0.db) + .await?; + for integration in integrations { + let specifics = integration.provider_specifics.unwrap(); + match integration.provider { + IntegrationProvider::JellyfinPush => { + let integration = JellyfinPushIntegration::new( + specifics.jellyfin_push_base_url.unwrap(), + specifics.jellyfin_push_username.unwrap(), + specifics.jellyfin_push_password.unwrap(), + &metadata_title, + &show_extra_information, + ); + integration.push_progress().await?; + } + _ => unreachable!(), + } + } + Ok(()) + } + pub async fn yank_integrations_data_for_user(&self, user_id: &String) -> GqlResult { let preferences = user_preferences_by_id(user_id, &self.0).await?; if preferences.general.disable_integrations { @@ -236,7 +273,7 @@ impl IntegrationService { let specifics = integration.clone().provider_specifics.unwrap(); let response = match integration.provider { IntegrationProvider::Audiobookshelf => { - let audiobookshelf = AudiobookshelfIntegration::new( + let audiobookshelf = AudiobookshelfYankIntegration::new( specifics.audiobookshelf_base_url.unwrap(), specifics.audiobookshelf_token.unwrap(), integration.sync_to_owned_collection, @@ -251,7 +288,7 @@ impl IntegrationService { .await } IntegrationProvider::Komga => { - let komga = KomgaIntegration::new( + let komga = KomgaYankIntegration::new( specifics.komga_base_url.unwrap(), specifics.komga_username.unwrap(), specifics.komga_password.unwrap(), diff --git a/crates/services/integration/src/push/jellyfin.rs b/crates/services/integration/src/push/jellyfin.rs new file mode 100644 index 0000000000..6713adbc46 --- /dev/null +++ b/crates/services/integration/src/push/jellyfin.rs @@ -0,0 +1,90 @@ +use external_utils::jellyfin::{get_authenticated_client, ItemsResponse}; +use media_models::SeenShowExtraInformation; +use serde_json::json; +use traits::TraceOk; + +pub(crate) struct JellyfinPushIntegration<'a> { + base_url: String, + username: String, + password: String, + metadata_title: &'a String, + show_extra_information: &'a Option, +} + +impl<'a> JellyfinPushIntegration<'a> { + pub const fn new( + base_url: String, + username: String, + password: String, + metadata_title: &'a String, + show_extra_information: &'a Option, + ) -> Self { + Self { + base_url, + username, + password, + metadata_title, + show_extra_information, + } + } + + pub async fn push_progress(&self) -> anyhow::Result<()> { + let (client, user_id) = + get_authenticated_client(&self.base_url, &self.username, &self.password).await?; + let json = + json!({ "Recursive": true, "SearchTerm": self.metadata_title, "HasTmdbId": true }); + let items = client + .get(format!("{}/Users/{}/Items", &self.base_url, user_id)) + .query(&json) + .send() + .await? + .json::() + .await?; + if let Some(selected_item) = items.items.first() { + let id = match self.show_extra_information { + Some(extra_information) => { + let mut return_id = None; + let id = selected_item.id.clone(); + let season = client + .get(format!("{}/Shows/{}/Seasons", self.base_url, id)) + .query(&json!({ "UserId": user_id })) + .send() + .await? + .json::() + .await? + .items + .into_iter() + .find(|s| s.index_number == Some(extra_information.season)); + if let Some(season) = season { + let episode = client + .get(format!("{}/Shows/{}/Episodes", self.base_url, id)) + .query(&json!({ "UserId": user_id, "SeasonId": season.id })) + .send() + .await? + .json::() + .await? + .items + .into_iter() + .find(|e| e.index_number == Some(extra_information.episode)); + return_id = episode.map(|e| e.id); + } + return_id + } + None => Some(selected_item.id.clone()), + }; + if let Some(id) = id { + client + .post(format!( + "{}/Users/{}/PlayedItems/{}", + self.base_url, user_id, id + )) + .send() + .await? + .json::() + .await + .trace_ok(); + } + } + Ok(()) + } +} diff --git a/crates/services/integration/src/push/mod.rs b/crates/services/integration/src/push/mod.rs index a4ec084770..d926a1d07e 100644 --- a/crates/services/integration/src/push/mod.rs +++ b/crates/services/integration/src/push/mod.rs @@ -1,2 +1,3 @@ +pub mod jellyfin; pub mod radarr; pub mod sonarr; diff --git a/crates/services/integration/src/push/radarr.rs b/crates/services/integration/src/push/radarr.rs index a1ec0e3b15..f625db5c5d 100644 --- a/crates/services/integration/src/push/radarr.rs +++ b/crates/services/integration/src/push/radarr.rs @@ -8,42 +8,42 @@ use radarr_api_rs::{ }; use traits::TraceOk; -pub(crate) struct RadarrIntegration { - radarr_base_url: String, - radarr_api_key: String, - radarr_profile_id: i32, - radarr_root_folder_path: String, +pub(crate) struct RadarrPushIntegration { + base_url: String, + api_key: String, + profile_id: i32, + root_folder_path: String, tmdb_id: String, } -impl RadarrIntegration { +impl RadarrPushIntegration { pub const fn new( - radarr_base_url: String, - radarr_api_key: String, - radarr_profile_id: i32, - radarr_root_folder_path: String, + base_url: String, + api_key: String, + profile_id: i32, + root_folder_path: String, tmdb_id: String, ) -> Self { Self { - radarr_base_url, - radarr_api_key, - radarr_profile_id, - radarr_root_folder_path, + base_url, + api_key, + profile_id, + root_folder_path, tmdb_id, } } - async fn radarr_push(&self) -> anyhow::Result<()> { + pub async fn push_progress(&self) -> anyhow::Result<()> { let mut configuration = RadarrConfiguration::new(); - configuration.base_path = self.radarr_base_url.clone(); + configuration.base_path = self.base_url.clone(); configuration.api_key = Some(RadarrApiKey { - key: self.radarr_api_key.clone(), + key: self.api_key.clone(), prefix: None, }); let mut resource = RadarrMovieResource::new(); resource.tmdb_id = Some(self.tmdb_id.parse().unwrap()); - resource.quality_profile_id = Some(self.radarr_profile_id); - resource.root_folder_path = Some(Some(self.radarr_root_folder_path.clone())); + resource.quality_profile_id = Some(self.profile_id); + resource.root_folder_path = Some(Some(self.root_folder_path.clone())); resource.monitored = Some(true); let mut options = RadarrAddMovieOptions::new(); options.search_for_movie = Some(true); @@ -54,8 +54,4 @@ impl RadarrIntegration { .trace_ok(); Ok(()) } - - pub async fn push_progress(&self) -> anyhow::Result<()> { - self.radarr_push().await - } } diff --git a/crates/services/integration/src/push/sonarr.rs b/crates/services/integration/src/push/sonarr.rs index e667d6d565..1024a8dac1 100644 --- a/crates/services/integration/src/push/sonarr.rs +++ b/crates/services/integration/src/push/sonarr.rs @@ -8,43 +8,43 @@ use sonarr_api_rs::{ }; use traits::TraceOk; -pub(crate) struct SonarrIntegration { - sonarr_base_url: String, - sonarr_api_key: String, - sonarr_profile_id: i32, - sonarr_root_folder_path: String, +pub(crate) struct SonarrPushIntegration { + base_url: String, + api_key: String, + profile_id: i32, + root_folder_path: String, tvdb_id: String, } -impl SonarrIntegration { +impl SonarrPushIntegration { pub const fn new( - sonarr_base_url: String, - sonarr_api_key: String, - sonarr_profile_id: i32, - sonarr_root_folder_path: String, + base_url: String, + api_key: String, + profile_id: i32, + root_folder_path: String, tvdb_id: String, ) -> Self { Self { - sonarr_base_url, - sonarr_api_key, - sonarr_profile_id, - sonarr_root_folder_path, + base_url, + api_key, + profile_id, + root_folder_path, tvdb_id, } } - async fn sonarr_push(&self) -> anyhow::Result<()> { + pub async fn push_progress(&self) -> anyhow::Result<()> { let mut configuration = SonarrConfiguration::new(); - configuration.base_path = self.sonarr_base_url.clone(); + configuration.base_path = self.base_url.clone(); configuration.api_key = Some(SonarrApiKey { - key: self.sonarr_api_key.clone(), + key: self.api_key.clone(), prefix: None, }); let mut resource = SonarrSeriesResource::new(); resource.title = Some(Some(self.tvdb_id.clone())); resource.tvdb_id = Some(self.tvdb_id.parse().unwrap()); - resource.quality_profile_id = Some(self.sonarr_profile_id); - resource.root_folder_path = Some(Some(self.sonarr_root_folder_path.clone())); + resource.quality_profile_id = Some(self.profile_id); + resource.root_folder_path = Some(Some(self.root_folder_path.clone())); resource.monitored = Some(true); resource.season_folder = Some(true); let mut options = SonarrAddSeriesOptions::new(); @@ -56,8 +56,4 @@ impl SonarrIntegration { .trace_ok(); Ok(()) } - - pub async fn push_progress(&self) -> anyhow::Result<()> { - self.sonarr_push().await - } } diff --git a/crates/services/integration/src/sink/emby.rs b/crates/services/integration/src/sink/emby.rs index cc21a57cb7..93c266549f 100644 --- a/crates/services/integration/src/sink/emby.rs +++ b/crates/services/integration/src/sink/emby.rs @@ -47,19 +47,18 @@ mod models { } } -pub(crate) struct EmbyIntegration { +pub(crate) struct EmbySinkIntegration { payload: String, db: DatabaseConnection, } -impl EmbyIntegration { +impl EmbySinkIntegration { pub const fn new(payload: String, db: DatabaseConnection) -> Self { Self { payload, db } } - async fn emby_progress(&self) -> Result { + pub async fn yank_progress(&self) -> Result { let payload: models::EmbyWebhookPayload = serde_json::from_str(&self.payload)?; - let runtime = payload .item .run_time_ticks @@ -68,7 +67,6 @@ impl EmbyIntegration { .playback_info .position_ticks .ok_or_else(|| anyhow::anyhow!("No position associated with this media"))?; - let (identifier, lot) = match payload.item.item_type.as_str() { "Movie" => { @@ -91,7 +89,6 @@ impl EmbyIntegration { } _ => bail!("Only movies and shows supported"), }; - Ok(ImportResult { metadata: vec![ImportOrExportMediaItem { lot, @@ -109,8 +106,4 @@ impl EmbyIntegration { ..Default::default() }) } - - pub async fn yank_progress(&self) -> Result { - self.emby_progress().await - } } diff --git a/crates/services/integration/src/sink/generic_json.rs b/crates/services/integration/src/sink/generic_json.rs index 5069396d4c..ffb9fa3179 100644 --- a/crates/services/integration/src/sink/generic_json.rs +++ b/crates/services/integration/src/sink/generic_json.rs @@ -1,15 +1,15 @@ use anyhow::{bail, Result}; use dependent_models::{CompleteExport, ImportResult}; -pub(crate) struct GenericJsonIntegration { +pub(crate) struct GenericJsonSinkIntegration { payload: String, } -impl GenericJsonIntegration { +impl GenericJsonSinkIntegration { pub const fn new(payload: String) -> Self { Self { payload } } - async fn generic_json_progress(&self) -> Result { + pub async fn yank_progress(&self) -> Result { let payload = match serde_json::from_str::(&self.payload) { Ok(val) => val, Err(err) => bail!(err), @@ -23,8 +23,4 @@ impl GenericJsonIntegration { ..Default::default() }) } - - pub async fn yank_progress(&self) -> Result { - self.generic_json_progress().await - } } diff --git a/crates/services/integration/src/sink/jellyfin.rs b/crates/services/integration/src/sink/jellyfin.rs index feced79b92..5e76411bfb 100644 --- a/crates/services/integration/src/sink/jellyfin.rs +++ b/crates/services/integration/src/sink/jellyfin.rs @@ -46,16 +46,16 @@ mod models { } } -pub(crate) struct JellyfinIntegration { +pub(crate) struct JellyfinSinkIntegration { payload: String, } -impl JellyfinIntegration { +impl JellyfinSinkIntegration { pub const fn new(payload: String) -> Self { Self { payload } } - async fn jellyfin_progress(&self) -> Result { + pub async fn yank_progress(&self) -> Result { let payload = serde_json::from_str::(&self.payload)?; let identifier = payload .item @@ -105,8 +105,4 @@ impl JellyfinIntegration { ..Default::default() }) } - - pub async fn yank_progress(&self) -> Result { - self.jellyfin_progress().await - } } diff --git a/crates/services/integration/src/sink/kodi.rs b/crates/services/integration/src/sink/kodi.rs index 0608a8491e..73001ce310 100644 --- a/crates/services/integration/src/sink/kodi.rs +++ b/crates/services/integration/src/sink/kodi.rs @@ -14,15 +14,15 @@ struct IntegrationMediaSeen { show_episode_number: Option, } -pub(crate) struct KodiIntegration { +pub(crate) struct KodiSinkIntegration { payload: String, } -impl KodiIntegration { +impl KodiSinkIntegration { pub const fn new(payload: String) -> Self { Self { payload } } - async fn kodi_progress(&self) -> Result { + pub async fn yank_progress(&self) -> Result { let payload = match serde_json::from_str::(&self.payload) { Ok(val) => val, Err(err) => bail!(err), @@ -45,8 +45,4 @@ impl KodiIntegration { ..Default::default() }) } - - pub async fn yank_progress(&self) -> Result { - self.kodi_progress().await - } } diff --git a/crates/services/integration/src/sink/plex.rs b/crates/services/integration/src/sink/plex.rs index c72c96e2f5..a2b3d5b934 100644 --- a/crates/services/integration/src/sink/plex.rs +++ b/crates/services/integration/src/sink/plex.rs @@ -52,13 +52,13 @@ mod models { } } -pub(crate) struct PlexIntegration { +pub(crate) struct PlexSinkIntegration { payload: String, plex_user: Option, db: DatabaseConnection, } -impl PlexIntegration { +impl PlexSinkIntegration { pub const fn new(payload: String, plex_user: Option, db: DatabaseConnection) -> Self { Self { payload, @@ -109,7 +109,7 @@ impl PlexIntegration { } } - async fn plex_progress(&self) -> Result { + pub async fn yank_progress(&self) -> Result { ryot_log!(debug, "Processing Plex payload {:#?}", self.payload); let payload = Self::parse_payload(&self.payload)?; @@ -149,8 +149,4 @@ impl PlexIntegration { ..Default::default() }) } - - pub async fn yank_progress(&self) -> Result { - self.plex_progress().await - } } diff --git a/crates/services/integration/src/yank/audiobookshelf.rs b/crates/services/integration/src/yank/audiobookshelf.rs index 9092fe3434..4a4bc7bbd2 100644 --- a/crates/services/integration/src/yank/audiobookshelf.rs +++ b/crates/services/integration/src/yank/audiobookshelf.rs @@ -14,14 +14,14 @@ use reqwest::header::{HeaderValue, AUTHORIZATION}; use rust_decimal_macros::dec; use specific_models::audiobookshelf::{self, LibrariesListResponse, ListResponse}; -pub(crate) struct AudiobookshelfIntegration { +pub(crate) struct AudiobookshelfYankIntegration { base_url: String, access_token: String, sync_to_owned_collection: Option, isbn_service: GoogleBooksService, } -impl AudiobookshelfIntegration { +impl AudiobookshelfYankIntegration { pub fn new( base_url: String, access_token: String, diff --git a/crates/services/integration/src/yank/komga.rs b/crates/services/integration/src/yank/komga.rs index 03ea600879..97bcf0d841 100644 --- a/crates/services/integration/src/yank/komga.rs +++ b/crates/services/integration/src/yank/komga.rs @@ -182,7 +182,7 @@ impl KomgaEventHandler { } } -pub(crate) struct KomgaIntegration { +pub(crate) struct KomgaYankIntegration { base_url: String, username: String, password: String, @@ -193,7 +193,7 @@ pub(crate) struct KomgaIntegration { type ProcessEventReturn = (CommitMediaInput, ImportOrExportMediaItemSeen); -impl KomgaIntegration { +impl KomgaYankIntegration { pub fn new( base_url: String, username: String, @@ -427,7 +427,7 @@ impl KomgaIntegration { Ok(()) } - async fn komga_progress(&self) -> Result { + pub async fn yank_progress(&self) -> Result { let mut result = ImportResult::default(); // DEV: This object needs global lifetime so we can continue to use the receiver if // we ever create more SSE Objects we may want to implement a higher level @@ -513,8 +513,4 @@ impl KomgaIntegration { Ok(result) } - - pub async fn yank_progress(&self) -> Result { - self.komga_progress().await - } } diff --git a/crates/services/miscellaneous/Cargo.toml b/crates/services/miscellaneous/Cargo.toml index 3507dd0b89..e4dd2314c5 100644 --- a/crates/services/miscellaneous/Cargo.toml +++ b/crates/services/miscellaneous/Cargo.toml @@ -4,7 +4,6 @@ version = "0.1.0" edition = "2021" [dependencies] -apalis = { workspace = true } application-utils = { path = "../../utils/application" } async-graphql = { workspace = true } background = { path = "../../background" } diff --git a/crates/services/miscellaneous/src/lib.rs b/crates/services/miscellaneous/src/lib.rs index 96fa86fd0b..1589e4c802 100644 --- a/crates/services/miscellaneous/src/lib.rs +++ b/crates/services/miscellaneous/src/lib.rs @@ -4,7 +4,6 @@ use std::{ sync::Arc, }; -use apalis::prelude::MessageQueue; use application_utils::get_current_date; use async_graphql::{Error, Result}; use background::{ApplicationJob, CoreApplicationJob}; @@ -42,11 +41,11 @@ use dependent_models::{ SearchResults, UserMetadataDetails, UserMetadataGroupDetails, UserPersonDetails, }; use dependent_utils::{ - after_media_seen_tasks, commit_metadata, commit_metadata_group_internal, - commit_metadata_internal, commit_person, create_partial_metadata, deploy_background_job, + commit_metadata, commit_metadata_group_internal, commit_metadata_internal, commit_person, + create_partial_metadata, deploy_after_handle_media_seen_tasks, deploy_background_job, deploy_update_metadata_job, get_metadata_provider, get_openlibrary_service, get_tmdb_non_media_service, get_users_and_cte_monitoring_entity, get_users_monitoring_entity, - is_metadata_finished_by_user, post_review, progress_update, + handle_after_media_seen_tasks, is_metadata_finished_by_user, post_review, progress_update, queue_media_state_changed_notification_for_user, queue_notifications_to_user_platforms, refresh_collection_to_entity_association, update_metadata_and_notify_users, }; @@ -420,7 +419,7 @@ ORDER BY RANDOM() LIMIT 10; metadata_id: &String, force_update: bool, ) -> Result { - deploy_update_metadata_job(metadata_id, force_update, &self.0.perform_application_job).await + deploy_update_metadata_job(metadata_id, force_update, &self.0).await } pub async fn metadata_details(&self, metadata_id: &String) -> Result { @@ -1089,11 +1088,8 @@ ORDER BY RANDOM() LIMIT 10; input: Vec, ) -> Result { self.0 - .perform_core_application_job - .clone() - .enqueue(CoreApplicationJob::BulkProgressUpdate(user_id, input)) - .await - .unwrap(); + .perform_core_application_job(CoreApplicationJob::BulkProgressUpdate(user_id, input)) + .await?; Ok(true) } @@ -1339,7 +1335,7 @@ ORDER BY RANDOM() LIMIT 10; seen.review_id = ActiveValue::Set(to_update_review_id); } let seen = seen.update(&self.0.db).await.unwrap(); - after_media_seen_tasks(seen, &self.0).await?; + deploy_after_handle_media_seen_tasks(seen, &self.0).await?; Ok(true) } @@ -1350,11 +1346,8 @@ ORDER BY RANDOM() LIMIT 10; .unwrap() .unwrap(); self.0 - .perform_application_job - .clone() - .enqueue(ApplicationJob::UpdatePerson(person.id)) - .await - .unwrap(); + .perform_application_job(ApplicationJob::UpdatePerson(person.id)) + .await?; Ok(true) } @@ -1368,11 +1361,8 @@ ORDER BY RANDOM() LIMIT 10; .unwrap() .unwrap(); self.0 - .perform_application_job - .clone() - .enqueue(ApplicationJob::UpdateMetadataGroup(metadata_group.id)) - .await - .unwrap(); + .perform_application_job(ApplicationJob::UpdateMetadataGroup(metadata_group.id)) + .await?; Ok(true) } @@ -1770,6 +1760,10 @@ ORDER BY RANDOM() LIMIT 10; } } + pub async fn handle_after_media_seen_tasks(&self, seen: seen::Model) -> Result<()> { + handle_after_media_seen_tasks(seen, &self.0).await + } + pub async fn delete_seen_item( &self, user_id: &String, @@ -1807,7 +1801,7 @@ ORDER BY RANDOM() LIMIT 10; si.delete(&self.0.db).await.trace_ok(); associate_user_with_entity(&self.0.db, user_id, metadata_id, EntityLot::Metadata) .await?; - after_media_seen_tasks(cloned_seen, &self.0).await?; + deploy_after_handle_media_seen_tasks(cloned_seen, &self.0).await?; Ok(StringIdObject { id: seen_id }) } else { Err(Error::new("This seen item does not exist".to_owned())) diff --git a/crates/services/statistics/src/lib.rs b/crates/services/statistics/src/lib.rs index 0bd5425cbf..d854035275 100644 --- a/crates/services/statistics/src/lib.rs +++ b/crates/services/statistics/src/lib.rs @@ -137,6 +137,10 @@ impl StatisticsService { daily_user_activity::Column::ShowDuration.sum(), "total_show_duration", ) + .column_as( + daily_user_activity::Column::VideoGameDuration.sum(), + "total_video_game_duration", + ) .column_as( daily_user_activity::Column::VideoGameCount.sum(), "video_game_count", diff --git a/crates/services/supporting/Cargo.toml b/crates/services/supporting/Cargo.toml index 212b9efadb..9a1e6c4692 100644 --- a/crates/services/supporting/Cargo.toml +++ b/crates/services/supporting/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] +async-graphql = { workspace = true } apalis = { workspace = true } background = { path = "../../background" } cache-service = { path = "../../services/cache" } diff --git a/crates/services/supporting/src/lib.rs b/crates/services/supporting/src/lib.rs index b0ecf3103e..717cf75901 100644 --- a/crates/services/supporting/src/lib.rs +++ b/crates/services/supporting/src/lib.rs @@ -1,6 +1,7 @@ use std::sync::Arc; -use apalis::prelude::MemoryStorage; +use apalis::prelude::{MemoryStorage, MessageQueue}; +use async_graphql::Result; use background::{ApplicationJob, CoreApplicationJob}; use cache_service::CacheService; use file_storage_service::FileStorageService; @@ -18,8 +19,9 @@ pub struct SupportingService { pub oidc_client: Option, pub commit_cache: Cache, pub file_storage_service: Arc, - pub perform_application_job: MemoryStorage, - pub perform_core_application_job: MemoryStorage, + + perform_application_job: MemoryStorage, + perform_core_application_job: MemoryStorage, } impl SupportingService { @@ -49,4 +51,22 @@ impl SupportingService { perform_core_application_job: perform_core_application_job.clone(), } } + + pub async fn perform_application_job(&self, job: ApplicationJob) -> Result<()> { + self.perform_application_job + .clone() + .enqueue(job) + .await + .unwrap(); + Ok(()) + } + + pub async fn perform_core_application_job(&self, job: CoreApplicationJob) -> Result<()> { + self.perform_core_application_job + .clone() + .enqueue(job) + .await + .unwrap(); + Ok(()) + } } diff --git a/crates/services/user/src/lib.rs b/crates/services/user/src/lib.rs index ae76c06424..f7f9f4bdcf 100644 --- a/crates/services/user/src/lib.rs +++ b/crates/services/user/src/lib.rs @@ -303,12 +303,7 @@ impl UserService { .await .ok(); } - deploy_job_to_calculate_user_activities_and_summary( - &self.0.perform_application_job, - &user.id, - false, - ) - .await; + deploy_job_to_calculate_user_activities_and_summary(&user.id, false, &self.0).await; Ok(RegisterResult::Ok(StringIdObject { id: user.id })) } @@ -799,8 +794,12 @@ impl UserService { )); } let lot = match input.provider { - IntegrationProvider::Audiobookshelf => IntegrationLot::Yank, - IntegrationProvider::Radarr | IntegrationProvider::Sonarr => IntegrationLot::Push, + IntegrationProvider::Audiobookshelf | IntegrationProvider::Komga => { + IntegrationLot::Yank + } + IntegrationProvider::Radarr + | IntegrationProvider::Sonarr + | IntegrationProvider::JellyfinPush => IntegrationLot::Push, _ => IntegrationLot::Sink, }; let to_insert = integration::ActiveModel { diff --git a/crates/utils/common/src/lib.rs b/crates/utils/common/src/lib.rs index a1dde168e7..a0ffd5d774 100644 --- a/crates/utils/common/src/lib.rs +++ b/crates/utils/common/src/lib.rs @@ -9,7 +9,7 @@ pub const USER_AGENT_STR: &str = const_str::concat!( AUTHOR, "/", PROJECT_NAME, - "-v", + "-", APP_VERSION, " (", AUTHOR_EMAIL, diff --git a/crates/utils/database/Cargo.toml b/crates/utils/database/Cargo.toml index a9d376194b..9937a07ea8 100644 --- a/crates/utils/database/Cargo.toml +++ b/crates/utils/database/Cargo.toml @@ -4,7 +4,6 @@ version = "0.1.0" edition = "2021" [dependencies] -apalis = { workspace = true } application-utils = { path = "../../utils/application" } async-graphql = { workspace = true } background = { path = "../../background" } diff --git a/crates/utils/database/src/lib.rs b/crates/utils/database/src/lib.rs index 04765c852b..f40c62baa5 100644 --- a/crates/utils/database/src/lib.rs +++ b/crates/utils/database/src/lib.rs @@ -1,6 +1,5 @@ use std::{collections::HashMap, sync::Arc}; -use apalis::prelude::{MemoryStorage, MessageQueue}; use application_utils::GraphqlRepresentation; use async_graphql::{Error, Result}; use background::ApplicationJob; @@ -34,7 +33,7 @@ use media_models::{ ShowSpecifics, VideoGameSpecifics, VisualNovelSpecifics, }; use migrations::AliasedCollectionToEntity; -use rust_decimal::prelude::ToPrimitive; +use rust_decimal::{prelude::ToPrimitive, Decimal}; use rust_decimal_macros::dec; use sea_orm::{ prelude::{Date, DateTimeUtc, Expr}, @@ -337,10 +336,8 @@ pub async fn add_entity_to_collection( } created }; - ss.perform_application_job - .enqueue(ApplicationJob::HandleEntityAddedToCollectionEvent(resp.id)) - .await - .unwrap(); + ss.perform_application_job(ApplicationJob::HandleEntityAddedToCollectionEvent(resp.id)) + .await?; Ok(true) } @@ -582,6 +579,7 @@ pub async fn calculate_user_activities_and_summary( podcast_specifics: Option, show_specifics: Option, video_game_specifics: Option, + manual_time_spent: Option, visual_novel_specifics: Option, anime_specifics: Option, manga_specifics: Option, @@ -637,6 +635,7 @@ pub async fn calculate_user_activities_and_summary( seen::Column::MetadataId, seen::Column::FinishedOn, seen::Column::LastUpdatedOn, + seen::Column::ManualTimeSpent, ]) .column_as(metadata::Column::Lot, "metadata_lot") .columns([ @@ -692,17 +691,22 @@ pub async fn calculate_user_activities_and_summary( if let Some(runtime) = visual_novel_extra.length { activity.visual_novel_duration += runtime; } + } else if let Some(_video_game_extra) = seen.video_game_specifics { + if let Some(manual_time_spent) = seen.manual_time_spent { + activity.video_game_duration += + (manual_time_spent / dec!(60)).to_i32().unwrap_or_default(); + } } match seen.metadata_lot { + MediaLot::Book => activity.book_count += 1, + MediaLot::Show => activity.show_count += 1, MediaLot::Anime => activity.anime_count += 1, + MediaLot::Movie => activity.movie_count += 1, MediaLot::Manga => activity.manga_count += 1, MediaLot::Podcast => activity.podcast_count += 1, - MediaLot::Show => activity.show_count += 1, MediaLot::VideoGame => activity.video_game_count += 1, - MediaLot::VisualNovel => activity.visual_novel_count += 1, - MediaLot::Book => activity.book_count += 1, MediaLot::AudioBook => activity.audio_book_count += 1, - MediaLot::Movie => activity.movie_count += 1, + MediaLot::VisualNovel => activity.visual_novel_count += 1, }; } @@ -745,11 +749,11 @@ pub async fn calculate_user_activities_and_summary( let date = item.posted_on.date_naive(); let activity = get_activity_count(item.id, &mut activities, user_id, date); match item.entity_lot { - EntityLot::Metadata => activity.metadata_review_count += 1, EntityLot::Person => activity.person_review_count += 1, - EntityLot::MetadataGroup => activity.metadata_group_review_count += 1, - EntityLot::Collection => activity.collection_review_count += 1, EntityLot::Exercise => activity.exercise_review_count += 1, + EntityLot::Metadata => activity.metadata_review_count += 1, + EntityLot::Collection => activity.collection_review_count += 1, + EntityLot::MetadataGroup => activity.metadata_group_review_count += 1, _ => {} } } @@ -784,7 +788,8 @@ pub async fn calculate_user_activities_and_summary( + activity.podcast_duration + activity.movie_duration + activity.show_duration - + activity.visual_novel_duration; + + activity.visual_novel_duration + + activity.video_game_duration; let mut model: daily_user_activity::ActiveModel = activity.into(); model.total_review_count = ActiveValue::Set(total_review_count); model.total_metadata_count = ActiveValue::Set(total_metadata_count); @@ -797,27 +802,23 @@ pub async fn calculate_user_activities_and_summary( } pub async fn deploy_job_to_calculate_user_activities_and_summary( - perform_application_job: &MemoryStorage, user_id: &String, calculate_from_beginning: bool, + ss: &Arc, ) { - perform_application_job - .clone() - .enqueue(ApplicationJob::RecalculateUserActivitiesAndSummary( - user_id.to_owned(), - calculate_from_beginning, - )) - .await - .unwrap(); + ss.perform_application_job(ApplicationJob::RecalculateUserActivitiesAndSummary( + user_id.to_owned(), + calculate_from_beginning, + )) + .await + .unwrap(); } pub async fn deploy_job_to_re_evaluate_user_workouts( user_id: &String, - perform_application_job: &MemoryStorage, + ss: &Arc, ) { - perform_application_job - .clone() - .enqueue(ApplicationJob::ReEvaluateUserWorkouts(user_id.to_owned())) + ss.perform_application_job(ApplicationJob::ReEvaluateUserWorkouts(user_id.to_owned())) .await .unwrap(); } diff --git a/crates/utils/dependent/Cargo.toml b/crates/utils/dependent/Cargo.toml index 8b23cc7585..4fbaf6c30c 100644 --- a/crates/utils/dependent/Cargo.toml +++ b/crates/utils/dependent/Cargo.toml @@ -5,7 +5,6 @@ edition = "2021" [dependencies] anyhow = { workspace = true } -apalis = { workspace = true } application-utils = { path = "../application" } async-graphql = { workspace = true } background = { path = "../../background" } diff --git a/crates/utils/dependent/src/lib.rs b/crates/utils/dependent/src/lib.rs index 9375f2f2b2..867263597e 100644 --- a/crates/utils/dependent/src/lib.rs +++ b/crates/utils/dependent/src/lib.rs @@ -1,7 +1,6 @@ use std::{collections::HashMap, iter::zip, sync::Arc}; use anyhow::{bail, Result as AnyhowResult}; -use apalis::prelude::{MemoryStorage, MessageQueue}; use application_utils::get_current_date; use async_graphql::{Enum, Error, Result}; use background::{ApplicationJob, CoreApplicationJob}; @@ -336,16 +335,12 @@ async fn deploy_associate_group_with_metadata_job( lot: MediaLot, source: MediaSource, identifier: String, - perform_application_job: &MemoryStorage, + ss: &Arc, ) -> Result<()> { - perform_application_job - .clone() - .enqueue(ApplicationJob::AssociateGroupWithMetadata( - lot, source, identifier, - )) - .await - .unwrap(); - Ok(()) + ss.perform_application_job(ApplicationJob::AssociateGroupWithMetadata( + lot, source, identifier, + )) + .await } #[allow(clippy::too_many_arguments)] @@ -388,14 +383,9 @@ async fn change_metadata_associations( .ok(); } for group_identifier in groups { - deploy_associate_group_with_metadata_job( - lot, - source, - group_identifier, - &ss.perform_application_job, - ) - .await - .ok(); + deploy_associate_group_with_metadata_job(lot, source, group_identifier, ss) + .await + .ok(); } Ok(()) } @@ -874,16 +864,13 @@ pub async fn commit_metadata( pub async fn deploy_update_metadata_job( metadata_id: &String, force_update: bool, - perform_application_job: &MemoryStorage, + ss: &Arc, ) -> Result { - perform_application_job - .clone() - .enqueue(ApplicationJob::UpdateMetadata( - metadata_id.to_owned(), - force_update, - )) - .await - .unwrap(); + ss.perform_application_job(ApplicationJob::UpdateMetadata( + metadata_id.to_owned(), + force_update, + )) + .await?; Ok(true) } @@ -892,8 +879,6 @@ pub async fn deploy_background_job( job_name: BackgroundJob, ss: &Arc, ) -> Result { - let core_storage = &mut ss.perform_core_application_job.clone(); - let storage = &mut ss.perform_application_job.clone(); match job_name { BackgroundJob::UpdateAllMetadata | BackgroundJob::UpdateAllExercises @@ -914,47 +899,37 @@ pub async fn deploy_background_job( .await .unwrap(); for metadata_id in many_metadata { - deploy_update_metadata_job(&metadata_id, true, storage).await?; + deploy_update_metadata_job(&metadata_id, true, ss).await?; } } BackgroundJob::UpdateAllExercises => { - storage - .enqueue(ApplicationJob::UpdateExerciseLibrary) - .await - .unwrap(); + ss.perform_application_job(ApplicationJob::UpdateExerciseLibrary) + .await?; } BackgroundJob::RecalculateCalendarEvents => { - storage - .enqueue(ApplicationJob::RecalculateCalendarEvents) - .await - .unwrap(); + ss.perform_application_job(ApplicationJob::RecalculateCalendarEvents) + .await?; } BackgroundJob::PerformBackgroundTasks => { - storage - .enqueue(ApplicationJob::PerformBackgroundTasks) - .await - .unwrap(); + ss.perform_application_job(ApplicationJob::PerformBackgroundTasks) + .await?; } BackgroundJob::SyncIntegrationsData => { - core_storage - .enqueue(CoreApplicationJob::SyncIntegrationsData(user_id.to_owned())) - .await - .unwrap(); + ss.perform_core_application_job(CoreApplicationJob::SyncIntegrationsData( + user_id.to_owned(), + )) + .await?; } BackgroundJob::CalculateUserActivitiesAndSummary => { - storage - .enqueue(ApplicationJob::RecalculateUserActivitiesAndSummary( - user_id.to_owned(), - true, - )) - .await - .unwrap(); + ss.perform_application_job(ApplicationJob::RecalculateUserActivitiesAndSummary( + user_id.to_owned(), + true, + )) + .await?; } BackgroundJob::ReEvaluateUserWorkouts => { - storage - .enqueue(ApplicationJob::ReEvaluateUserWorkouts(user_id.to_owned())) - .await - .unwrap(); + ss.perform_application_job(ApplicationJob::ReEvaluateUserWorkouts(user_id.to_owned())) + .await?; } }; Ok(true) @@ -1058,17 +1033,14 @@ pub async fn post_review( let user = user_by_id(&ss.db, &insert.user_id.unwrap()).await?; // DEV: Do not send notification if updating a review if input.review_id.is_none() { - ss.perform_core_application_job - .clone() - .enqueue(CoreApplicationJob::ReviewPosted(ReviewPostedEvent { - obj_title, - entity_lot, - obj_id: id, - username: user.name, - review_id: insert.id.clone().unwrap(), - })) - .await - .unwrap(); + ss.perform_core_application_job(CoreApplicationJob::ReviewPosted(ReviewPostedEvent { + obj_title, + entity_lot, + obj_id: id, + username: user.name, + review_id: insert.id.clone().unwrap(), + })) + .await?; } } Ok(StringIdObject { @@ -1201,7 +1173,18 @@ pub async fn is_metadata_finished_by_user( Ok((is_finished, seen_history)) } -pub async fn after_media_seen_tasks(seen: seen::Model, ss: &Arc) -> Result<()> { +pub async fn deploy_after_handle_media_seen_tasks( + seen: seen::Model, + ss: &Arc, +) -> Result<()> { + ss.perform_application_job(ApplicationJob::HandleAfterMediaSeenTasks(seen)) + .await +} + +pub async fn handle_after_media_seen_tasks( + seen: seen::Model, + ss: &Arc, +) -> Result<()> { let add_entity_to_collection = |collection_name: &str| { add_entity_to_collection( &seen.user_id, @@ -1506,7 +1489,11 @@ pub async fn progress_update( .set_with_expiry(cache, ss.config.server.progress_update_threshold) .await?; } - after_media_seen_tasks(seen, ss).await?; + if seen.state == SeenState::Completed { + ss.perform_application_job(ApplicationJob::HandleOnSeenComplete(seen.id.clone())) + .await?; + } + deploy_after_handle_media_seen_tasks(seen, ss).await?; Ok(ProgressUpdateResultUnion::Ok(StringIdObject { id })) } @@ -1841,7 +1828,7 @@ pub async fn create_or_update_workout( } let data = insert.insert(&ss.db).await?; if to_update_workout.is_some() { - deploy_job_to_re_evaluate_user_workouts(user_id, &ss.perform_application_job).await; + deploy_job_to_re_evaluate_user_workouts(user_id, ss).await; } Ok(data.id) } diff --git a/crates/utils/external/Cargo.toml b/crates/utils/external/Cargo.toml new file mode 100644 index 0000000000..b5dbcb8a64 --- /dev/null +++ b/crates/utils/external/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "external-utils" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = { workspace = true } +common-utils = { path = "../common" } +reqwest = { workspace = true } +sea-orm = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +tracing = { workspace = true } + +[package.metadata.cargo-machete] +ignored = ["tracing"] diff --git a/crates/utils/external/src/lib.rs b/crates/utils/external/src/lib.rs new file mode 100644 index 0000000000..96ce6c4a4c --- /dev/null +++ b/crates/utils/external/src/lib.rs @@ -0,0 +1,109 @@ +use anyhow::Result; +use common_utils::{ryot_log, APPLICATION_JSON_HEADER, USER_AGENT_STR}; +use reqwest::{ + header::{HeaderMap, HeaderValue, ACCEPT, AUTHORIZATION, USER_AGENT}, + Client, ClientBuilder, +}; +use sea_orm::prelude::DateTimeUtc; +use serde::{Deserialize, Serialize}; + +pub mod jellyfin { + use super::*; + + #[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)] + pub enum MediaType { + Movie, + Series, + Episode, + #[serde(untagged)] + Unknown(String), + } + + #[derive(Serialize, Deserialize, Debug, Clone)] + #[serde(rename_all = "PascalCase")] + pub struct ItemProviderIdsPayload { + pub tmdb: Option, + } + + #[derive(Serialize, Deserialize, Debug, Clone)] + #[serde(rename_all = "PascalCase")] + pub struct ItemUserData { + pub last_played_date: Option, + pub is_favorite: Option, + } + + #[derive(Serialize, Deserialize, Debug, Clone)] + #[serde(rename_all = "PascalCase")] + pub struct ItemResponse { + pub id: String, + pub name: String, + #[serde(rename = "Type")] + pub type_: Option, + pub index_number: Option, + pub series_id: Option, + pub series_name: Option, + pub user_data: Option, + pub parent_index_number: Option, + pub provider_ids: Option, + } + + #[derive(Serialize, Deserialize, Debug, Clone)] + #[serde(rename_all = "PascalCase")] + pub struct ItemsResponse { + pub items: Vec, + } + + #[derive(Serialize, Deserialize, Debug, Clone)] + #[serde(rename_all = "PascalCase")] + pub struct AuthenticateResponse { + pub user: ItemResponse, + pub access_token: String, + } + + pub async fn get_authenticated_client( + base_url: &String, + username: &String, + password: &String, + ) -> Result<(Client, String)> { + let mut emby_header_value = + r#"MediaBrowser , Client="other", Device="script", DeviceId="script", Version="0.0.0""# + .to_string(); + let uri = format!("{}/Users/AuthenticateByName", base_url); + let client = Client::new(); + let authenticate_request = client + .post(uri) + .header(AUTHORIZATION, &emby_header_value) + .json(&serde_json::json!({ "Username": username, "Pw": password })); + ryot_log!(debug, "Authentication request: {:?}", authenticate_request); + let authenticate = authenticate_request + .send() + .await + .unwrap() + .json::() + .await + .unwrap(); + ryot_log!( + debug, + "Authenticated with token: {}", + authenticate.access_token + ); + + emby_header_value.push_str(&format!(r#", Token="{}""#, authenticate.access_token)); + + let mut headers = HeaderMap::new(); + headers.insert(USER_AGENT, HeaderValue::from_static(USER_AGENT_STR)); + headers.insert(ACCEPT, APPLICATION_JSON_HEADER.clone()); + headers.insert( + AUTHORIZATION, + HeaderValue::from_str(&emby_header_value).unwrap(), + ); + let client: Client = ClientBuilder::new() + .default_headers(headers) + .build() + .unwrap(); + let user_id = authenticate.user.id; + ryot_log!(debug, "Authenticated as user id: {}", user_id); + + Ok((client, user_id)) + } +} diff --git a/docs/content/integrations.md b/docs/content/integrations.md index 7082258728..c70a4a4b50 100644 --- a/docs/content/integrations.md +++ b/docs/content/integrations.md @@ -3,28 +3,10 @@ Integrations can be used to continuously update your media progress or inform external services about changes. They can be of following types: -- _Push_: Ryot sends data to an external service when an event occurs. - _Yank_: Progress data is downloaded from an externally running server at a periodic interval. - _Sink_: An external client publishes progress updates to the Ryot server. - -## Push integrations - -You can enable the following push integrations: - -### Radarr - -Automatically add movies in the selected collections to Radarr. - -1. Obtain your Radarr API key by going to the Radarr general settings page. -2. Fill the inputs in the integration settings page with the correct details. - -### Sonarr - -Automatically add shows in the selected collections to Sonarr. - -1. Obtain your Sonarr API key by going to the Sonarr general settings page. -2. Fill the inputs in the integration settings page with the correct details. +- _Push_: Ryot sends data to an external service when an event occurs. ## Yank integrations @@ -166,3 +148,31 @@ format. The format of the JSON file should be `CompleteExport` as described in t You can use this to build integrations with other services that Ryot does not support natively. + +## Push integrations + +You can enable the following push integrations: + +### Radarr + +Automatically add movies in the selected collections to Radarr. + +1. Obtain your Radarr API key by going to the Radarr general settings page. +2. Fill the inputs in the integration settings page with the correct details. + +### Sonarr + +Automatically add shows in the selected collections to Sonarr. + +1. Obtain your Sonarr API key by going to the Sonarr general settings page. +2. Fill the inputs in the integration settings page with the correct details. + +### Jellyfin + +Automatically mark movies and shows as watched in Jellyfin when you mark them as watched +in Ryot. + +1. While creating the integration, you will be asked to provide your Jellyfin username and + password. +2. Every time you mark a movie or show as watched in Ryot, the integration will mark it as + watched in Jellyfin. diff --git a/docs/pyproject.toml b/docs/pyproject.toml index 59dc852d88..3c3997dfb7 100644 --- a/docs/pyproject.toml +++ b/docs/pyproject.toml @@ -4,7 +4,7 @@ version = "0.1.0" description = "Documentation website for Ryot" authors = ["Diptesh Choudhuri "] license = "GPL-v3" -readme = "README.md" +package-mode = false [tool.poetry.dependencies] python = "^3.11" diff --git a/libs/generated/package.json b/libs/generated/package.json index 97ed4aa0fd..a9509561a6 100644 --- a/libs/generated/package.json +++ b/libs/generated/package.json @@ -5,7 +5,7 @@ "graphql": "16.9.0" }, "devDependencies": { - "@graphql-codegen/cli": "5.0.2", - "@graphql-codegen/client-preset": "4.3.3" + "@graphql-codegen/cli": "5.0.3", + "@graphql-codegen/client-preset": "4.4.0" } } diff --git a/libs/generated/src/graphql/backend/gql.ts b/libs/generated/src/graphql/backend/gql.ts index 5a48d7a738..6b0fe4ff17 100644 --- a/libs/generated/src/graphql/backend/gql.ts +++ b/libs/generated/src/graphql/backend/gql.ts @@ -22,7 +22,7 @@ const documents = { "query GenreDetails($input: GenreDetailsInput!) {\n genreDetails(input: $input) {\n details {\n id\n name\n numItems\n }\n contents {\n details {\n total\n nextPage\n }\n items\n }\n }\n}": types.GenreDetailsDocument, "query GenresList($input: SearchInput!) {\n genresList(input: $input) {\n details {\n total\n nextPage\n }\n items {\n id\n name\n numItems\n }\n }\n}": types.GenresListDocument, "query ImportReports {\n importReports {\n id\n source\n startedOn\n finishedOn\n wasSuccess\n details {\n import {\n total\n }\n failedItems {\n lot\n step\n identifier\n error\n }\n }\n }\n}": types.ImportReportsDocument, - "query LatestUserSummary {\n latestUserSummary {\n totalMetadataReviewCount\n totalCollectionReviewCount\n totalMetadataGroupReviewCount\n totalPersonReviewCount\n measurementCount\n workoutCount\n totalWorkoutDuration\n audioBookCount\n totalAudioBookDuration\n animeCount\n bookCount\n totalBookPages\n podcastCount\n totalPodcastDuration\n mangaCount\n movieCount\n totalMovieDuration\n showCount\n totalShowDuration\n videoGameCount\n visualNovelCount\n totalVisualNovelDuration\n totalWorkoutPersonalBests\n totalWorkoutWeight\n totalWorkoutReps\n totalWorkoutDistance\n totalWorkoutRestTime\n totalMetadataCount\n totalReviewCount\n totalCount\n totalDuration\n }\n}": types.LatestUserSummaryDocument, + "query LatestUserSummary {\n latestUserSummary {\n totalMetadataReviewCount\n totalCollectionReviewCount\n totalMetadataGroupReviewCount\n totalPersonReviewCount\n measurementCount\n workoutCount\n totalWorkoutDuration\n audioBookCount\n totalAudioBookDuration\n animeCount\n bookCount\n totalBookPages\n podcastCount\n totalPodcastDuration\n mangaCount\n movieCount\n totalMovieDuration\n showCount\n totalShowDuration\n videoGameCount\n totalVideoGameDuration\n visualNovelCount\n totalVisualNovelDuration\n totalWorkoutPersonalBests\n totalWorkoutWeight\n totalWorkoutReps\n totalWorkoutDistance\n totalWorkoutRestTime\n totalMetadataCount\n totalReviewCount\n totalCount\n totalDuration\n }\n}": types.LatestUserSummaryDocument, "query MetadataDetails($metadataId: String!) {\n metadataDetails(metadataId: $metadataId) {\n id\n lot\n title\n source\n isNsfw\n isPartial\n sourceUrl\n identifier\n description\n suggestions\n publishYear\n publishDate\n providerRating\n productionStatus\n originalLanguage\n genres {\n id\n name\n }\n group {\n id\n name\n part\n }\n assets {\n images\n videos {\n videoId\n source\n }\n }\n creators {\n name\n items {\n id\n name\n image\n character\n }\n }\n watchProviders {\n name\n image\n languages\n }\n animeSpecifics {\n episodes\n }\n audioBookSpecifics {\n runtime\n }\n bookSpecifics {\n pages\n }\n movieSpecifics {\n runtime\n }\n mangaSpecifics {\n volumes\n chapters\n }\n podcastSpecifics {\n episodes {\n id\n title\n overview\n thumbnail\n number\n runtime\n publishDate\n }\n totalEpisodes\n }\n showSpecifics {\n totalSeasons\n totalEpisodes\n runtime\n seasons {\n id\n seasonNumber\n name\n overview\n backdropImages\n posterImages\n episodes {\n id\n name\n posterImages\n episodeNumber\n publishDate\n name\n overview\n runtime\n }\n }\n }\n visualNovelSpecifics {\n length\n }\n videoGameSpecifics {\n platforms\n }\n }\n}": types.MetadataDetailsDocument, "query MetadataGroupDetails($metadataGroupId: String!) {\n metadataGroupDetails(metadataGroupId: $metadataGroupId) {\n contents\n sourceUrl\n details {\n id\n title\n lot\n source\n displayImages\n identifier\n parts\n isPartial\n }\n }\n}": types.MetadataGroupDetailsDocument, "query MetadataGroupSearch($input: MetadataGroupSearchInput!) {\n metadataGroupSearch(input: $input) {\n details {\n total\n nextPage\n }\n items {\n identifier\n name\n image\n parts\n }\n }\n}": types.MetadataGroupSearchDocument, @@ -98,7 +98,7 @@ export function graphql(source: "query ImportReports {\n importReports {\n i /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "query LatestUserSummary {\n latestUserSummary {\n totalMetadataReviewCount\n totalCollectionReviewCount\n totalMetadataGroupReviewCount\n totalPersonReviewCount\n measurementCount\n workoutCount\n totalWorkoutDuration\n audioBookCount\n totalAudioBookDuration\n animeCount\n bookCount\n totalBookPages\n podcastCount\n totalPodcastDuration\n mangaCount\n movieCount\n totalMovieDuration\n showCount\n totalShowDuration\n videoGameCount\n visualNovelCount\n totalVisualNovelDuration\n totalWorkoutPersonalBests\n totalWorkoutWeight\n totalWorkoutReps\n totalWorkoutDistance\n totalWorkoutRestTime\n totalMetadataCount\n totalReviewCount\n totalCount\n totalDuration\n }\n}"): (typeof documents)["query LatestUserSummary {\n latestUserSummary {\n totalMetadataReviewCount\n totalCollectionReviewCount\n totalMetadataGroupReviewCount\n totalPersonReviewCount\n measurementCount\n workoutCount\n totalWorkoutDuration\n audioBookCount\n totalAudioBookDuration\n animeCount\n bookCount\n totalBookPages\n podcastCount\n totalPodcastDuration\n mangaCount\n movieCount\n totalMovieDuration\n showCount\n totalShowDuration\n videoGameCount\n visualNovelCount\n totalVisualNovelDuration\n totalWorkoutPersonalBests\n totalWorkoutWeight\n totalWorkoutReps\n totalWorkoutDistance\n totalWorkoutRestTime\n totalMetadataCount\n totalReviewCount\n totalCount\n totalDuration\n }\n}"]; +export function graphql(source: "query LatestUserSummary {\n latestUserSummary {\n totalMetadataReviewCount\n totalCollectionReviewCount\n totalMetadataGroupReviewCount\n totalPersonReviewCount\n measurementCount\n workoutCount\n totalWorkoutDuration\n audioBookCount\n totalAudioBookDuration\n animeCount\n bookCount\n totalBookPages\n podcastCount\n totalPodcastDuration\n mangaCount\n movieCount\n totalMovieDuration\n showCount\n totalShowDuration\n videoGameCount\n totalVideoGameDuration\n visualNovelCount\n totalVisualNovelDuration\n totalWorkoutPersonalBests\n totalWorkoutWeight\n totalWorkoutReps\n totalWorkoutDistance\n totalWorkoutRestTime\n totalMetadataCount\n totalReviewCount\n totalCount\n totalDuration\n }\n}"): (typeof documents)["query LatestUserSummary {\n latestUserSummary {\n totalMetadataReviewCount\n totalCollectionReviewCount\n totalMetadataGroupReviewCount\n totalPersonReviewCount\n measurementCount\n workoutCount\n totalWorkoutDuration\n audioBookCount\n totalAudioBookDuration\n animeCount\n bookCount\n totalBookPages\n podcastCount\n totalPodcastDuration\n mangaCount\n movieCount\n totalMovieDuration\n showCount\n totalShowDuration\n videoGameCount\n totalVideoGameDuration\n visualNovelCount\n totalVisualNovelDuration\n totalWorkoutPersonalBests\n totalWorkoutWeight\n totalWorkoutReps\n totalWorkoutDistance\n totalWorkoutRestTime\n totalMetadataCount\n totalReviewCount\n totalCount\n totalDuration\n }\n}"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/libs/generated/src/graphql/backend/graphql.ts b/libs/generated/src/graphql/backend/graphql.ts index 897d36e744..00c26b990f 100644 --- a/libs/generated/src/graphql/backend/graphql.ts +++ b/libs/generated/src/graphql/backend/graphql.ts @@ -359,6 +359,7 @@ export type DailyUserActivityItem = { totalPodcastDuration: Scalars['Int']['output']; totalReviewCount: Scalars['Int']['output']; totalShowDuration: Scalars['Int']['output']; + totalVideoGameDuration: Scalars['Int']['output']; totalVisualNovelDuration: Scalars['Int']['output']; totalWorkoutDistance: Scalars['Int']['output']; totalWorkoutDuration: Scalars['Int']['output']; @@ -834,7 +835,8 @@ export enum IntegrationProvider { Audiobookshelf = 'AUDIOBOOKSHELF', Emby = 'EMBY', GenericJson = 'GENERIC_JSON', - Jellyfin = 'JELLYFIN', + JellyfinPush = 'JELLYFIN_PUSH', + JellyfinSink = 'JELLYFIN_SINK', Kodi = 'KODI', Komga = 'KOMGA', Plex = 'PLEX', @@ -845,6 +847,9 @@ export enum IntegrationProvider { export type IntegrationSourceSpecificsInput = { audiobookshelfBaseUrl?: InputMaybe; audiobookshelfToken?: InputMaybe; + jellyfinPushBaseUrl?: InputMaybe; + jellyfinPushPassword?: InputMaybe; + jellyfinPushUsername?: InputMaybe; komgaBaseUrl?: InputMaybe; komgaPassword?: InputMaybe; komgaProvider?: InputMaybe; @@ -3078,7 +3083,7 @@ export type ImportReportsQuery = { importReports: Array<{ id: string, source: Im export type LatestUserSummaryQueryVariables = Exact<{ [key: string]: never; }>; -export type LatestUserSummaryQuery = { latestUserSummary: { totalMetadataReviewCount: number, totalCollectionReviewCount: number, totalMetadataGroupReviewCount: number, totalPersonReviewCount: number, measurementCount: number, workoutCount: number, totalWorkoutDuration: number, audioBookCount: number, totalAudioBookDuration: number, animeCount: number, bookCount: number, totalBookPages: number, podcastCount: number, totalPodcastDuration: number, mangaCount: number, movieCount: number, totalMovieDuration: number, showCount: number, totalShowDuration: number, videoGameCount: number, visualNovelCount: number, totalVisualNovelDuration: number, totalWorkoutPersonalBests: number, totalWorkoutWeight: number, totalWorkoutReps: number, totalWorkoutDistance: number, totalWorkoutRestTime: number, totalMetadataCount: number, totalReviewCount: number, totalCount: number, totalDuration: number } }; +export type LatestUserSummaryQuery = { latestUserSummary: { totalMetadataReviewCount: number, totalCollectionReviewCount: number, totalMetadataGroupReviewCount: number, totalPersonReviewCount: number, measurementCount: number, workoutCount: number, totalWorkoutDuration: number, audioBookCount: number, totalAudioBookDuration: number, animeCount: number, bookCount: number, totalBookPages: number, podcastCount: number, totalPodcastDuration: number, mangaCount: number, movieCount: number, totalMovieDuration: number, showCount: number, totalShowDuration: number, videoGameCount: number, totalVideoGameDuration: number, visualNovelCount: number, totalVisualNovelDuration: number, totalWorkoutPersonalBests: number, totalWorkoutWeight: number, totalWorkoutReps: number, totalWorkoutDistance: number, totalWorkoutRestTime: number, totalMetadataCount: number, totalReviewCount: number, totalCount: number, totalDuration: number } }; export type MetadataDetailsQueryVariables = Exact<{ metadataId: Scalars['String']['input']; @@ -3420,7 +3425,7 @@ export const ExercisesListDocument = {"kind":"Document","definitions":[{"kind":" export const GenreDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GenreDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"GenreDetailsInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"genreDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"numItems"}}]}},{"kind":"Field","name":{"kind":"Name","value":"contents"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}},{"kind":"Field","name":{"kind":"Name","value":"items"}}]}}]}}]}}]} as unknown as DocumentNode; export const GenresListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GenresList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"SearchInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"genresList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"numItems"}}]}}]}}]}}]} as unknown as DocumentNode; export const ImportReportsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ImportReports"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"importReports"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"source"}},{"kind":"Field","name":{"kind":"Name","value":"startedOn"}},{"kind":"Field","name":{"kind":"Name","value":"finishedOn"}},{"kind":"Field","name":{"kind":"Name","value":"wasSuccess"}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"import"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}}]}},{"kind":"Field","name":{"kind":"Name","value":"failedItems"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"step"}},{"kind":"Field","name":{"kind":"Name","value":"identifier"}},{"kind":"Field","name":{"kind":"Name","value":"error"}}]}}]}}]}}]}}]} as unknown as DocumentNode; -export const LatestUserSummaryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"LatestUserSummary"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"latestUserSummary"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalMetadataReviewCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalCollectionReviewCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalMetadataGroupReviewCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalPersonReviewCount"}},{"kind":"Field","name":{"kind":"Name","value":"measurementCount"}},{"kind":"Field","name":{"kind":"Name","value":"workoutCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalWorkoutDuration"}},{"kind":"Field","name":{"kind":"Name","value":"audioBookCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalAudioBookDuration"}},{"kind":"Field","name":{"kind":"Name","value":"animeCount"}},{"kind":"Field","name":{"kind":"Name","value":"bookCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalBookPages"}},{"kind":"Field","name":{"kind":"Name","value":"podcastCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalPodcastDuration"}},{"kind":"Field","name":{"kind":"Name","value":"mangaCount"}},{"kind":"Field","name":{"kind":"Name","value":"movieCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalMovieDuration"}},{"kind":"Field","name":{"kind":"Name","value":"showCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalShowDuration"}},{"kind":"Field","name":{"kind":"Name","value":"videoGameCount"}},{"kind":"Field","name":{"kind":"Name","value":"visualNovelCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalVisualNovelDuration"}},{"kind":"Field","name":{"kind":"Name","value":"totalWorkoutPersonalBests"}},{"kind":"Field","name":{"kind":"Name","value":"totalWorkoutWeight"}},{"kind":"Field","name":{"kind":"Name","value":"totalWorkoutReps"}},{"kind":"Field","name":{"kind":"Name","value":"totalWorkoutDistance"}},{"kind":"Field","name":{"kind":"Name","value":"totalWorkoutRestTime"}},{"kind":"Field","name":{"kind":"Name","value":"totalMetadataCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalReviewCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalDuration"}}]}}]}}]} as unknown as DocumentNode; +export const LatestUserSummaryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"LatestUserSummary"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"latestUserSummary"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalMetadataReviewCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalCollectionReviewCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalMetadataGroupReviewCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalPersonReviewCount"}},{"kind":"Field","name":{"kind":"Name","value":"measurementCount"}},{"kind":"Field","name":{"kind":"Name","value":"workoutCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalWorkoutDuration"}},{"kind":"Field","name":{"kind":"Name","value":"audioBookCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalAudioBookDuration"}},{"kind":"Field","name":{"kind":"Name","value":"animeCount"}},{"kind":"Field","name":{"kind":"Name","value":"bookCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalBookPages"}},{"kind":"Field","name":{"kind":"Name","value":"podcastCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalPodcastDuration"}},{"kind":"Field","name":{"kind":"Name","value":"mangaCount"}},{"kind":"Field","name":{"kind":"Name","value":"movieCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalMovieDuration"}},{"kind":"Field","name":{"kind":"Name","value":"showCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalShowDuration"}},{"kind":"Field","name":{"kind":"Name","value":"videoGameCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalVideoGameDuration"}},{"kind":"Field","name":{"kind":"Name","value":"visualNovelCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalVisualNovelDuration"}},{"kind":"Field","name":{"kind":"Name","value":"totalWorkoutPersonalBests"}},{"kind":"Field","name":{"kind":"Name","value":"totalWorkoutWeight"}},{"kind":"Field","name":{"kind":"Name","value":"totalWorkoutReps"}},{"kind":"Field","name":{"kind":"Name","value":"totalWorkoutDistance"}},{"kind":"Field","name":{"kind":"Name","value":"totalWorkoutRestTime"}},{"kind":"Field","name":{"kind":"Name","value":"totalMetadataCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalReviewCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}},{"kind":"Field","name":{"kind":"Name","value":"totalDuration"}}]}}]}}]} as unknown as DocumentNode; export const MetadataDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"MetadataDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"metadataId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"metadataDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"metadataId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"metadataId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"source"}},{"kind":"Field","name":{"kind":"Name","value":"isNsfw"}},{"kind":"Field","name":{"kind":"Name","value":"isPartial"}},{"kind":"Field","name":{"kind":"Name","value":"sourceUrl"}},{"kind":"Field","name":{"kind":"Name","value":"identifier"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"suggestions"}},{"kind":"Field","name":{"kind":"Name","value":"publishYear"}},{"kind":"Field","name":{"kind":"Name","value":"publishDate"}},{"kind":"Field","name":{"kind":"Name","value":"providerRating"}},{"kind":"Field","name":{"kind":"Name","value":"productionStatus"}},{"kind":"Field","name":{"kind":"Name","value":"originalLanguage"}},{"kind":"Field","name":{"kind":"Name","value":"genres"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"group"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"part"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"images"}},{"kind":"Field","name":{"kind":"Name","value":"videos"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"videoId"}},{"kind":"Field","name":{"kind":"Name","value":"source"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"creators"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"image"}},{"kind":"Field","name":{"kind":"Name","value":"character"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"watchProviders"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"image"}},{"kind":"Field","name":{"kind":"Name","value":"languages"}}]}},{"kind":"Field","name":{"kind":"Name","value":"animeSpecifics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episodes"}}]}},{"kind":"Field","name":{"kind":"Name","value":"audioBookSpecifics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"runtime"}}]}},{"kind":"Field","name":{"kind":"Name","value":"bookSpecifics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"pages"}}]}},{"kind":"Field","name":{"kind":"Name","value":"movieSpecifics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"runtime"}}]}},{"kind":"Field","name":{"kind":"Name","value":"mangaSpecifics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"volumes"}},{"kind":"Field","name":{"kind":"Name","value":"chapters"}}]}},{"kind":"Field","name":{"kind":"Name","value":"podcastSpecifics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episodes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"overview"}},{"kind":"Field","name":{"kind":"Name","value":"thumbnail"}},{"kind":"Field","name":{"kind":"Name","value":"number"}},{"kind":"Field","name":{"kind":"Name","value":"runtime"}},{"kind":"Field","name":{"kind":"Name","value":"publishDate"}}]}},{"kind":"Field","name":{"kind":"Name","value":"totalEpisodes"}}]}},{"kind":"Field","name":{"kind":"Name","value":"showSpecifics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalSeasons"}},{"kind":"Field","name":{"kind":"Name","value":"totalEpisodes"}},{"kind":"Field","name":{"kind":"Name","value":"runtime"}},{"kind":"Field","name":{"kind":"Name","value":"seasons"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"seasonNumber"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"overview"}},{"kind":"Field","name":{"kind":"Name","value":"backdropImages"}},{"kind":"Field","name":{"kind":"Name","value":"posterImages"}},{"kind":"Field","name":{"kind":"Name","value":"episodes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"posterImages"}},{"kind":"Field","name":{"kind":"Name","value":"episodeNumber"}},{"kind":"Field","name":{"kind":"Name","value":"publishDate"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"overview"}},{"kind":"Field","name":{"kind":"Name","value":"runtime"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"visualNovelSpecifics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"length"}}]}},{"kind":"Field","name":{"kind":"Name","value":"videoGameSpecifics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"platforms"}}]}}]}}]}}]} as unknown as DocumentNode; export const MetadataGroupDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"MetadataGroupDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"metadataGroupId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"metadataGroupDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"metadataGroupId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"metadataGroupId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"contents"}},{"kind":"Field","name":{"kind":"Name","value":"sourceUrl"}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"source"}},{"kind":"Field","name":{"kind":"Name","value":"displayImages"}},{"kind":"Field","name":{"kind":"Name","value":"identifier"}},{"kind":"Field","name":{"kind":"Name","value":"parts"}},{"kind":"Field","name":{"kind":"Name","value":"isPartial"}}]}}]}}]}}]} as unknown as DocumentNode; export const MetadataGroupSearchDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"MetadataGroupSearch"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"MetadataGroupSearchInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"metadataGroupSearch"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"identifier"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"image"}},{"kind":"Field","name":{"kind":"Name","value":"parts"}}]}}]}}]}}]} as unknown as DocumentNode; diff --git a/libs/graphql/src/backend/mutations/combined.gql b/libs/graphql/src/backend/mutations/combined.gql index abebb61cca..50545a0d3e 100644 --- a/libs/graphql/src/backend/mutations/combined.gql +++ b/libs/graphql/src/backend/mutations/combined.gql @@ -1,251 +1,256 @@ mutation RegisterUser($input: RegisterUserInput!) { - registerUser(input: $input){ - __typename - ... on RegisterError { - error - } - ... on StringIdObject { - id - } - } + registerUser(input: $input) { + __typename + ... on RegisterError { + error + } + ... on StringIdObject { + id + } + } } mutation LoginUser($input: AuthUserInput!) { - loginUser(input: $input) { - __typename - ... on LoginError { - error - } - ... on LoginResponse { - apiKey - } - } + loginUser(input: $input) { + __typename + ... on LoginError { + error + } + ... on LoginResponse { + apiKey + } + } } mutation AddEntityToCollection($input: ChangeCollectionToEntityInput!) { - addEntityToCollection(input: $input) + addEntityToCollection(input: $input) } mutation CommitMetadata($input: CommitMediaInput!) { - commitMetadata(input: $input) { - id - } + commitMetadata(input: $input) { + id + } } mutation CommitMetadataGroup($input: CommitMediaInput!) { - commitMetadataGroup(input: $input) { - id - } + commitMetadataGroup(input: $input) { + id + } } mutation CommitPerson($input: CommitPersonInput!) { - commitPerson(input: $input) { - id - } + commitPerson(input: $input) { + id + } } mutation CreateCustomExercise($input: ExerciseInput!) { - createCustomExercise(input: $input) + createCustomExercise(input: $input) } mutation UpdateCustomExercise($input: UpdateCustomExerciseInput!) { - updateCustomExercise(input: $input) + updateCustomExercise(input: $input) } mutation UpdateUserIntegration($input: UpdateUserIntegrationInput!) { - updateUserIntegration(input: $input) + updateUserIntegration(input: $input) } mutation CreateCustomMetadata($input: CreateCustomMetadataInput!) { - createCustomMetadata(input: $input) { - id - } + createCustomMetadata(input: $input) { + id + } } mutation CreateOrUpdateCollection($input: CreateOrUpdateCollectionInput!) { - createOrUpdateCollection(input: $input) { - id - } + createOrUpdateCollection(input: $input) { + id + } } mutation CreateReviewComment($input: CreateReviewCommentInput!) { - createReviewComment(input: $input) + createReviewComment(input: $input) } mutation CreateUserMeasurement($input: UserMeasurementInput!) { - createUserMeasurement(input: $input) + createUserMeasurement(input: $input) } -mutation CreateUserNotificationPlatform($input: CreateUserNotificationPlatformInput!) { - createUserNotificationPlatform(input: $input) +mutation CreateUserNotificationPlatform( + $input: CreateUserNotificationPlatformInput! +) { + createUserNotificationPlatform(input: $input) } mutation CreateUserIntegration($input: CreateUserIntegrationInput!) { - createUserIntegration(input: $input) { - id - } + createUserIntegration(input: $input) { + id + } } mutation CreateOrUpdateUserWorkout($input: UserWorkoutInput!) { - createOrUpdateUserWorkout(input: $input) + createOrUpdateUserWorkout(input: $input) } mutation CreateOrUpdateUserWorkoutTemplate($input: UserWorkoutInput!) { - createOrUpdateUserWorkoutTemplate(input: $input) + createOrUpdateUserWorkoutTemplate(input: $input) } mutation DeleteCollection($collectionName: String!) { - deleteCollection(collectionName: $collectionName) + deleteCollection(collectionName: $collectionName) } mutation DeleteReview($reviewId: String!) { - deleteReview(reviewId: $reviewId) + deleteReview(reviewId: $reviewId) } mutation DeleteS3Object($key: String!) { - deleteS3Object(key: $key) + deleteS3Object(key: $key) } mutation DeleteSeenItem($seenId: String!) { - deleteSeenItem(seenId: $seenId) { - id - } + deleteSeenItem(seenId: $seenId) { + id + } } mutation DeleteUser($toDeleteUserId: String!) { - deleteUser(toDeleteUserId: $toDeleteUserId) + deleteUser(toDeleteUserId: $toDeleteUserId) } mutation DeleteUserIntegration($integrationId: String!) { - deleteUserIntegration(integrationId: $integrationId) + deleteUserIntegration(integrationId: $integrationId) } mutation DeleteUserMeasurement($timestamp: DateTime!) { - deleteUserMeasurement(timestamp: $timestamp) + deleteUserMeasurement(timestamp: $timestamp) } mutation DeleteUserNotificationPlatform($notificationId: String!) { - deleteUserNotificationPlatform(notificationId: $notificationId) + deleteUserNotificationPlatform(notificationId: $notificationId) } mutation DeleteUserWorkout($workoutId: String!) { - deleteUserWorkout(workoutId: $workoutId) + deleteUserWorkout(workoutId: $workoutId) } mutation DeleteUserWorkoutTemplate($workoutTemplateId: String!) { - deleteUserWorkoutTemplate(workoutTemplateId: $workoutTemplateId) + deleteUserWorkoutTemplate(workoutTemplateId: $workoutTemplateId) } mutation DeployBackgroundJob($jobName: BackgroundJob!) { - deployBackgroundJob(jobName: $jobName) + deployBackgroundJob(jobName: $jobName) } mutation DeployBulkProgressUpdate($input: [ProgressUpdateInput!]!) { - deployBulkProgressUpdate(input: $input) + deployBulkProgressUpdate(input: $input) } mutation DeployExportJob { - deployExportJob + deployExportJob } mutation DeployImportJob($input: DeployImportJobInput!) { - deployImportJob(input: $input) + deployImportJob(input: $input) } mutation DeployUpdateMetadataJob($metadataId: String!) { - deployUpdateMetadataJob(metadataId: $metadataId) + deployUpdateMetadataJob(metadataId: $metadataId) } mutation DeployUpdatePersonJob($personId: String!) { - deployUpdatePersonJob(personId: $personId) + deployUpdatePersonJob(personId: $personId) } mutation DeployUpdateMetadataGroupJob($metadataGroupId: String!) { - deployUpdateMetadataGroupJob(metadataGroupId: $metadataGroupId) + deployUpdateMetadataGroupJob(metadataGroupId: $metadataGroupId) } mutation UpdateSeenItem($input: UpdateSeenItemInput!) { - updateSeenItem(input: $input) + updateSeenItem(input: $input) } -mutation UpdateUserNotificationPlatform($input: UpdateUserNotificationPlatformInput!) { - updateUserNotificationPlatform(input: $input) +mutation UpdateUserNotificationPlatform( + $input: UpdateUserNotificationPlatformInput! +) { + updateUserNotificationPlatform(input: $input) } -mutation UpdateUserWorkoutAttributes($input: UpdateUserWorkoutAttributesInput!) { - updateUserWorkoutAttributes(input: $input) +mutation UpdateUserWorkoutAttributes( + $input: UpdateUserWorkoutAttributesInput! +) { + updateUserWorkoutAttributes(input: $input) } mutation GenerateAuthToken { - generateAuthToken + generateAuthToken } mutation MergeMetadata($mergeFrom: String!, $mergeInto: String!) { - mergeMetadata(mergeFrom: $mergeFrom, mergeInto: $mergeInto) + mergeMetadata(mergeFrom: $mergeFrom, mergeInto: $mergeInto) } mutation DisassociateMetadata($metadataId: String!) { - disassociateMetadata(metadataId: $metadataId) + disassociateMetadata(metadataId: $metadataId) } mutation CreateOrUpdateReview($input: CreateOrUpdateReviewInput!) { - createOrUpdateReview(input: $input) { - id - } + createOrUpdateReview(input: $input) { + id + } } mutation PresignedPutS3Url($input: PresignedPutUrlInput!) { - presignedPutS3Url(input: $input) { - key - uploadUrl - } + presignedPutS3Url(input: $input) { + key + uploadUrl + } } mutation RemoveEntityFromCollection($input: ChangeCollectionToEntityInput!) { - removeEntityFromCollection(input: $input) { - id - } + removeEntityFromCollection(input: $input) { + id + } } mutation TestUserNotificationPlatforms { - testUserNotificationPlatforms + testUserNotificationPlatforms } mutation UpdateUser($input: UpdateUserInput!) { - updateUser(input: $input) { - id - } + updateUser(input: $input) { + id + } } mutation UpdateUserPreference($input: UpdateComplexJsonInput!) { - updateUserPreference(input: $input) + updateUserPreference(input: $input) } - mutation CreateAccessLink($input: CreateAccessLinkInput!) { - createAccessLink(input: $input) { - id - } + createAccessLink(input: $input) { + id + } } mutation ProcessAccessLink($input: ProcessAccessLinkInput!) { - processAccessLink(input: $input) { - __typename - ... on ProcessAccessLinkError { - error - } - ... on ProcessAccessLinkResponse { - apiKey - redirectTo - tokenValidForDays - } - } + processAccessLink(input: $input) { + __typename + ... on ProcessAccessLinkError { + error + } + ... on ProcessAccessLinkResponse { + apiKey + redirectTo + tokenValidForDays + } + } } mutation RevokeAccessLink($accessLinkId: String!) { - revokeAccessLink(accessLinkId: $accessLinkId) + revokeAccessLink(accessLinkId: $accessLinkId) } mutation UpdateUserExerciseSettings($input: UpdateUserExerciseSettings!) { - updateUserExerciseSettings(input: $input) + updateUserExerciseSettings(input: $input) } diff --git a/libs/graphql/src/backend/queries/CollectionContents.gql b/libs/graphql/src/backend/queries/CollectionContents.gql index 0d5ea54dfc..8d3da84d59 100644 --- a/libs/graphql/src/backend/queries/CollectionContents.gql +++ b/libs/graphql/src/backend/queries/CollectionContents.gql @@ -1,26 +1,26 @@ query CollectionContents($input: CollectionContentsInput!) { - collectionContents(input: $input) { - user { - id - name - } - reviews { - ...ReviewItemPart - } - results { - details { - total - nextPage - } - items { - entityId - entityLot - } - } - details { - name - description - createdOn - } - } + collectionContents(input: $input) { + user { + id + name + } + reviews { + ...ReviewItemPart + } + results { + details { + total + nextPage + } + items { + entityId + entityLot + } + } + details { + name + description + createdOn + } + } } diff --git a/libs/graphql/src/backend/queries/CoreDetails.gql b/libs/graphql/src/backend/queries/CoreDetails.gql index 5871f3ff87..c7dd702298 100644 --- a/libs/graphql/src/backend/queries/CoreDetails.gql +++ b/libs/graphql/src/backend/queries/CoreDetails.gql @@ -1,16 +1,16 @@ query CoreDetails { - coreDetails { - isPro - version - docsLink - pageLimit - websiteUrl - smtpEnabled - oidcEnabled - signupAllowed - repositoryLink - localAuthDisabled - fileStorageEnabled - tokenValidForDays - } + coreDetails { + isPro + version + docsLink + pageLimit + websiteUrl + smtpEnabled + oidcEnabled + signupAllowed + repositoryLink + localAuthDisabled + fileStorageEnabled + tokenValidForDays + } } diff --git a/libs/graphql/src/backend/queries/ExerciseDetails.gql b/libs/graphql/src/backend/queries/ExerciseDetails.gql index 75f93fc4cc..b0aed0111b 100644 --- a/libs/graphql/src/backend/queries/ExerciseDetails.gql +++ b/libs/graphql/src/backend/queries/ExerciseDetails.gql @@ -1,17 +1,17 @@ query ExerciseDetails($exerciseId: String!) { - exerciseDetails(exerciseId: $exerciseId) { - id - lot - source - level - force - mechanic - equipment - muscles - createdByUserId - attributes { - instructions - images - } - } + exerciseDetails(exerciseId: $exerciseId) { + id + lot + source + level + force + mechanic + equipment + muscles + createdByUserId + attributes { + instructions + images + } + } } diff --git a/libs/graphql/src/backend/queries/ExerciseParameters.gql b/libs/graphql/src/backend/queries/ExerciseParameters.gql index e1b8ae1c5e..ff18e7a0a5 100644 --- a/libs/graphql/src/backend/queries/ExerciseParameters.gql +++ b/libs/graphql/src/backend/queries/ExerciseParameters.gql @@ -1,17 +1,17 @@ query ExerciseParameters { - exerciseParameters { - downloadRequired - filters { - type - level - force - mechanic - equipment - muscle - } - lotMapping { - lot - bests - } - } + exerciseParameters { + downloadRequired + filters { + type + level + force + mechanic + equipment + muscle + } + lotMapping { + lot + bests + } + } } diff --git a/libs/graphql/src/backend/queries/ExercisesList.gql b/libs/graphql/src/backend/queries/ExercisesList.gql index ee41535a6f..071cb233df 100644 --- a/libs/graphql/src/backend/queries/ExercisesList.gql +++ b/libs/graphql/src/backend/queries/ExercisesList.gql @@ -1,16 +1,16 @@ query ExercisesList($input: ExercisesListInput!) { - exercisesList(input: $input) { - details { - total - nextPage - } - items { - id - lot - image - muscle - numTimesInteracted - lastUpdatedOn - } - } + exercisesList(input: $input) { + details { + total + nextPage + } + items { + id + lot + image + muscle + numTimesInteracted + lastUpdatedOn + } + } } diff --git a/libs/graphql/src/backend/queries/GenreDetails.gql b/libs/graphql/src/backend/queries/GenreDetails.gql index 8ac6efc6b4..2cf2db54be 100644 --- a/libs/graphql/src/backend/queries/GenreDetails.gql +++ b/libs/graphql/src/backend/queries/GenreDetails.gql @@ -1,16 +1,16 @@ query GenreDetails($input: GenreDetailsInput!) { - genreDetails(input: $input) { - details { - id - name - numItems - } - contents { - details { - total - nextPage - } - items - } - } + genreDetails(input: $input) { + details { + id + name + numItems + } + contents { + details { + total + nextPage + } + items + } + } } diff --git a/libs/graphql/src/backend/queries/GenresList.gql b/libs/graphql/src/backend/queries/GenresList.gql index a81024ab19..26192b446c 100644 --- a/libs/graphql/src/backend/queries/GenresList.gql +++ b/libs/graphql/src/backend/queries/GenresList.gql @@ -1,13 +1,13 @@ query GenresList($input: SearchInput!) { - genresList(input: $input) { - details { - total - nextPage - } - items { - id - name - numItems - } - } + genresList(input: $input) { + details { + total + nextPage + } + items { + id + name + numItems + } + } } diff --git a/libs/graphql/src/backend/queries/ImportReports.gql b/libs/graphql/src/backend/queries/ImportReports.gql index 5896a37a50..8b20a9581a 100644 --- a/libs/graphql/src/backend/queries/ImportReports.gql +++ b/libs/graphql/src/backend/queries/ImportReports.gql @@ -1,20 +1,20 @@ query ImportReports { - importReports { - id - source - startedOn - finishedOn - wasSuccess - details { - import { - total - } - failedItems { - lot - step - identifier - error - } - } - } + importReports { + id + source + startedOn + finishedOn + wasSuccess + details { + import { + total + } + failedItems { + lot + step + identifier + error + } + } + } } diff --git a/libs/graphql/src/backend/queries/LatestUserSummary.gql b/libs/graphql/src/backend/queries/LatestUserSummary.gql index f3bdb50439..23fc3cab31 100644 --- a/libs/graphql/src/backend/queries/LatestUserSummary.gql +++ b/libs/graphql/src/backend/queries/LatestUserSummary.gql @@ -1,35 +1,36 @@ query LatestUserSummary { - latestUserSummary { - totalMetadataReviewCount - totalCollectionReviewCount - totalMetadataGroupReviewCount - totalPersonReviewCount - measurementCount - workoutCount - totalWorkoutDuration - audioBookCount - totalAudioBookDuration - animeCount - bookCount - totalBookPages - podcastCount - totalPodcastDuration - mangaCount - movieCount - totalMovieDuration - showCount - totalShowDuration - videoGameCount - visualNovelCount - totalVisualNovelDuration - totalWorkoutPersonalBests - totalWorkoutWeight - totalWorkoutReps - totalWorkoutDistance - totalWorkoutRestTime - totalMetadataCount - totalReviewCount - totalCount - totalDuration - } + latestUserSummary { + totalMetadataReviewCount + totalCollectionReviewCount + totalMetadataGroupReviewCount + totalPersonReviewCount + measurementCount + workoutCount + totalWorkoutDuration + audioBookCount + totalAudioBookDuration + animeCount + bookCount + totalBookPages + podcastCount + totalPodcastDuration + mangaCount + movieCount + totalMovieDuration + showCount + totalShowDuration + videoGameCount + totalVideoGameDuration + visualNovelCount + totalVisualNovelDuration + totalWorkoutPersonalBests + totalWorkoutWeight + totalWorkoutReps + totalWorkoutDistance + totalWorkoutRestTime + totalMetadataCount + totalReviewCount + totalCount + totalDuration + } } diff --git a/libs/graphql/src/backend/queries/MetadataDetails.gql b/libs/graphql/src/backend/queries/MetadataDetails.gql index 6f5fdde134..caa2c9aea4 100644 --- a/libs/graphql/src/backend/queries/MetadataDetails.gql +++ b/libs/graphql/src/backend/queries/MetadataDetails.gql @@ -1,106 +1,106 @@ query MetadataDetails($metadataId: String!) { - metadataDetails(metadataId: $metadataId) { - id - lot - title - source - isNsfw - isPartial - sourceUrl - identifier - description - suggestions - publishYear - publishDate - providerRating - productionStatus - originalLanguage - genres { - id - name - } - group { - id - name - part - } - assets { - images - videos { - videoId - source - } - } - creators { - name - items { - id - name - image - character - } - } - watchProviders { - name - image - languages - } - animeSpecifics { - episodes - } - audioBookSpecifics { - runtime - } - bookSpecifics { - pages - } - movieSpecifics { - runtime - } - mangaSpecifics { - volumes - chapters - } - podcastSpecifics { - episodes { - id - title - overview - thumbnail - number - runtime - publishDate - } - totalEpisodes - } - showSpecifics { - totalSeasons - totalEpisodes - runtime - seasons { - id - seasonNumber - name - overview - backdropImages - posterImages - episodes { - id - name - posterImages - episodeNumber - publishDate - name - overview - runtime - } - } - } - visualNovelSpecifics { - length - } - videoGameSpecifics { - platforms - } - } + metadataDetails(metadataId: $metadataId) { + id + lot + title + source + isNsfw + isPartial + sourceUrl + identifier + description + suggestions + publishYear + publishDate + providerRating + productionStatus + originalLanguage + genres { + id + name + } + group { + id + name + part + } + assets { + images + videos { + videoId + source + } + } + creators { + name + items { + id + name + image + character + } + } + watchProviders { + name + image + languages + } + animeSpecifics { + episodes + } + audioBookSpecifics { + runtime + } + bookSpecifics { + pages + } + movieSpecifics { + runtime + } + mangaSpecifics { + volumes + chapters + } + podcastSpecifics { + episodes { + id + title + overview + thumbnail + number + runtime + publishDate + } + totalEpisodes + } + showSpecifics { + totalSeasons + totalEpisodes + runtime + seasons { + id + seasonNumber + name + overview + backdropImages + posterImages + episodes { + id + name + posterImages + episodeNumber + publishDate + name + overview + runtime + } + } + } + visualNovelSpecifics { + length + } + videoGameSpecifics { + platforms + } + } } diff --git a/libs/graphql/src/backend/queries/MetadataGroupDetails.gql b/libs/graphql/src/backend/queries/MetadataGroupDetails.gql index d9dfec1bb0..e88e1f388c 100644 --- a/libs/graphql/src/backend/queries/MetadataGroupDetails.gql +++ b/libs/graphql/src/backend/queries/MetadataGroupDetails.gql @@ -1,16 +1,16 @@ query MetadataGroupDetails($metadataGroupId: String!) { - metadataGroupDetails(metadataGroupId: $metadataGroupId) { - contents - sourceUrl - details { - id - title - lot - source - displayImages - identifier - parts - isPartial - } - } + metadataGroupDetails(metadataGroupId: $metadataGroupId) { + contents + sourceUrl + details { + id + title + lot + source + displayImages + identifier + parts + isPartial + } + } } diff --git a/libs/graphql/src/backend/queries/MetadataGroupSearch.gql b/libs/graphql/src/backend/queries/MetadataGroupSearch.gql index 2a5f6f1d7e..8f9b48fe4c 100644 --- a/libs/graphql/src/backend/queries/MetadataGroupSearch.gql +++ b/libs/graphql/src/backend/queries/MetadataGroupSearch.gql @@ -1,14 +1,14 @@ query MetadataGroupSearch($input: MetadataGroupSearchInput!) { - metadataGroupSearch(input: $input) { - details { - total - nextPage - } - items { - identifier - name - image - parts - } - } + metadataGroupSearch(input: $input) { + details { + total + nextPage + } + items { + identifier + name + image + parts + } + } } diff --git a/libs/graphql/src/backend/queries/MetadataList.gql b/libs/graphql/src/backend/queries/MetadataList.gql index f8661edb5e..ef571424dd 100644 --- a/libs/graphql/src/backend/queries/MetadataList.gql +++ b/libs/graphql/src/backend/queries/MetadataList.gql @@ -1,9 +1,9 @@ query MetadataList($input: MetadataListInput!) { - metadataList(input: $input) { - details { - total - nextPage - } - items - } + metadataList(input: $input) { + details { + total + nextPage + } + items + } } diff --git a/libs/graphql/src/backend/queries/MetadataSearch.gql b/libs/graphql/src/backend/queries/MetadataSearch.gql index 09346fe334..cc777ab81f 100644 --- a/libs/graphql/src/backend/queries/MetadataSearch.gql +++ b/libs/graphql/src/backend/queries/MetadataSearch.gql @@ -1,18 +1,18 @@ query MetadataSearch($input: MetadataSearchInput!) { - metadataSearch(input: $input) { - details { - total - nextPage - } - items { - databaseId - hasInteracted - item { - identifier - title - image - publishYear - } - } - } + metadataSearch(input: $input) { + details { + total + nextPage + } + items { + databaseId + hasInteracted + item { + identifier + title + image + publishYear + } + } + } } diff --git a/libs/graphql/src/backend/queries/PeopleSearch.gql b/libs/graphql/src/backend/queries/PeopleSearch.gql index 30225d9977..06180cadbb 100644 --- a/libs/graphql/src/backend/queries/PeopleSearch.gql +++ b/libs/graphql/src/backend/queries/PeopleSearch.gql @@ -1,14 +1,14 @@ query PeopleSearch($input: PeopleSearchInput!) { - peopleSearch(input: $input) { - details { - total - nextPage - } - items { - identifier - name - image - birthYear - } - } + peopleSearch(input: $input) { + details { + total + nextPage + } + items { + identifier + name + image + birthYear + } + } } diff --git a/libs/graphql/src/backend/queries/PersonDetails.gql b/libs/graphql/src/backend/queries/PersonDetails.gql index c663285f6e..d8d31b67c3 100644 --- a/libs/graphql/src/backend/queries/PersonDetails.gql +++ b/libs/graphql/src/backend/queries/PersonDetails.gql @@ -1,27 +1,27 @@ query PersonDetails($personId: String!) { - personDetails(personId: $personId) { - sourceUrl - details { - id - name - source - identifier - isPartial - description - birthDate - deathDate - place - website - gender - displayImages - } - contents { - name - count - items { - character - metadataId - } - } - } + personDetails(personId: $personId) { + sourceUrl + details { + id + name + source + identifier + isPartial + description + birthDate + deathDate + place + website + gender + displayImages + } + contents { + name + count + items { + character + metadataId + } + } + } } diff --git a/libs/graphql/src/backend/queries/UserDetails.gql b/libs/graphql/src/backend/queries/UserDetails.gql index 0c8c91894b..b0988914cd 100644 --- a/libs/graphql/src/backend/queries/UserDetails.gql +++ b/libs/graphql/src/backend/queries/UserDetails.gql @@ -1,11 +1,11 @@ query UserDetails { - userDetails { - __typename - ... on User { - id - lot - name - oidcIssuerId - } - } + userDetails { + __typename + ... on User { + id + lot + name + oidcIssuerId + } + } } diff --git a/libs/graphql/src/backend/queries/UserExerciseDetails.gql b/libs/graphql/src/backend/queries/UserExerciseDetails.gql index 55309ca4a9..2604e85489 100644 --- a/libs/graphql/src/backend/queries/UserExerciseDetails.gql +++ b/libs/graphql/src/backend/queries/UserExerciseDetails.gql @@ -1,46 +1,46 @@ query UserExerciseDetails($exerciseId: String!) { - userExerciseDetails(exerciseId: $exerciseId) { - collections { - ...CollectionPart - } - reviews { - ...ReviewItemPart - } - history { - idx - workoutId - workoutEndOn - bestSet { - ...WorkoutSetRecordPart - } - } - details { - exerciseId - createdOn - lastUpdatedOn - exerciseNumTimesInteracted - exerciseExtraInformation { - settings { - setRestTimers { - ...SetRestTimersPart - } - } - lifetimeStats { - weight - reps - distance - duration - personalBestsAchieved - } - personalBests { - lot - sets { - workoutId - exerciseIdx - setIdx - } - } - } - } - } + userExerciseDetails(exerciseId: $exerciseId) { + collections { + ...CollectionPart + } + reviews { + ...ReviewItemPart + } + history { + idx + workoutId + workoutEndOn + bestSet { + ...WorkoutSetRecordPart + } + } + details { + exerciseId + createdOn + lastUpdatedOn + exerciseNumTimesInteracted + exerciseExtraInformation { + settings { + setRestTimers { + ...SetRestTimersPart + } + } + lifetimeStats { + weight + reps + distance + duration + personalBestsAchieved + } + personalBests { + lot + sets { + workoutId + exerciseIdx + setIdx + } + } + } + } + } } diff --git a/libs/graphql/src/backend/queries/UserMeasurementsList.gql b/libs/graphql/src/backend/queries/UserMeasurementsList.gql index f4752491cb..7b189c308b 100644 --- a/libs/graphql/src/backend/queries/UserMeasurementsList.gql +++ b/libs/graphql/src/backend/queries/UserMeasurementsList.gql @@ -1,33 +1,33 @@ query UserMeasurementsList($input: UserMeasurementsListInput!) { - userMeasurementsList(input: $input) { - timestamp - name - comment - stats { - weight - bodyMassIndex - totalBodyWater - muscle - leanBodyMass - bodyFat - boneMass - visceralFat - waistCircumference - waistToHeightRatio - hipCircumference - waistToHipRatio - chestCircumference - thighCircumference - bicepsCircumference - neckCircumference - bodyFatCaliper - chestSkinfold - abdominalSkinfold - thighSkinfold - basalMetabolicRate - totalDailyEnergyExpenditure - calories - custom - } - } + userMeasurementsList(input: $input) { + timestamp + name + comment + stats { + weight + bodyMassIndex + totalBodyWater + muscle + leanBodyMass + bodyFat + boneMass + visceralFat + waistCircumference + waistToHeightRatio + hipCircumference + waistToHipRatio + chestCircumference + thighCircumference + bicepsCircumference + neckCircumference + bodyFatCaliper + chestSkinfold + abdominalSkinfold + thighSkinfold + basalMetabolicRate + totalDailyEnergyExpenditure + calories + custom + } + } } diff --git a/libs/graphql/src/backend/queries/UserMetadataDetails.gql b/libs/graphql/src/backend/queries/UserMetadataDetails.gql index 3c242068f2..9b3bdeb9a6 100644 --- a/libs/graphql/src/backend/queries/UserMetadataDetails.gql +++ b/libs/graphql/src/backend/queries/UserMetadataDetails.gql @@ -1,39 +1,39 @@ query UserMetadataDetails($metadataId: String!) { - userMetadataDetails(metadataId: $metadataId) { - mediaReason - hasInteracted - collections { - ...CollectionPart - } - inProgress { - ...SeenPart - } - history { - ...SeenPart - } - averageRating - reviews { - ...ReviewItemPart - } - seenByAllCount - seenByUserCount - nextEntry { - season - volume - episode - chapter - } - showProgress { - timesSeen - seasonNumber - episodes { - episodeNumber - timesSeen - } - } - podcastProgress { - episodeNumber - timesSeen - } - } + userMetadataDetails(metadataId: $metadataId) { + mediaReason + hasInteracted + collections { + ...CollectionPart + } + inProgress { + ...SeenPart + } + history { + ...SeenPart + } + averageRating + reviews { + ...ReviewItemPart + } + seenByAllCount + seenByUserCount + nextEntry { + season + volume + episode + chapter + } + showProgress { + timesSeen + seasonNumber + episodes { + episodeNumber + timesSeen + } + } + podcastProgress { + episodeNumber + timesSeen + } + } } diff --git a/libs/graphql/src/backend/queries/UserMetadataGroupDetails.gql b/libs/graphql/src/backend/queries/UserMetadataGroupDetails.gql index 8ad73f8770..fcf020378f 100644 --- a/libs/graphql/src/backend/queries/UserMetadataGroupDetails.gql +++ b/libs/graphql/src/backend/queries/UserMetadataGroupDetails.gql @@ -1,10 +1,10 @@ query UserMetadataGroupDetails($metadataGroupId: String!) { - userMetadataGroupDetails(metadataGroupId: $metadataGroupId) { - reviews { - ...ReviewItemPart - } - collections { - ...CollectionPart - } - } + userMetadataGroupDetails(metadataGroupId: $metadataGroupId) { + reviews { + ...ReviewItemPart + } + collections { + ...CollectionPart + } + } } diff --git a/libs/graphql/src/backend/queries/UserPersonDetails.gql b/libs/graphql/src/backend/queries/UserPersonDetails.gql index 79cdb6e256..4461438471 100644 --- a/libs/graphql/src/backend/queries/UserPersonDetails.gql +++ b/libs/graphql/src/backend/queries/UserPersonDetails.gql @@ -1,10 +1,10 @@ query UserPersonDetails($personId: String!) { - userPersonDetails(personId: $personId) { - collections { - ...CollectionPart - } - reviews { - ...ReviewItemPart - } - } + userPersonDetails(personId: $personId) { + collections { + ...CollectionPart + } + reviews { + ...ReviewItemPart + } + } } diff --git a/libs/graphql/src/backend/queries/UserPreferences.gql b/libs/graphql/src/backend/queries/UserPreferences.gql index 0994072e8c..e52c602b15 100644 --- a/libs/graphql/src/backend/queries/UserPreferences.gql +++ b/libs/graphql/src/backend/queries/UserPreferences.gql @@ -1,94 +1,94 @@ query UserPreferences { - userPreferences { - general { - reviewScale - gridPacking - displayNsfw - disableVideos - persistQueries - disableReviews - disableIntegrations - disableWatchProviders - disableNavigationAnimation - dashboard { - section - hidden - numElements - } - watchProviders { - lot - values - } - } - fitness { - measurements { - custom { - name - dataType - } - inbuilt { - weight - bodyMassIndex - totalBodyWater - muscle - leanBodyMass - bodyFat - boneMass - visceralFat - waistCircumference - waistToHeightRatio - hipCircumference - waistToHipRatio - chestCircumference - thighCircumference - bicepsCircumference - neckCircumference - bodyFatCaliper - chestSkinfold - abdominalSkinfold - thighSkinfold - basalMetabolicRate - totalDailyEnergyExpenditure - calories - } - } - exercises { - unitSystem - setRestTimers { - ...SetRestTimersPart - } - } - } - notifications { - toSend - enabled - } - featuresEnabled { - others { - calendar - collections - } - fitness { - enabled - workouts - templates - measurements - } - media { - enabled - anime - audioBook - book - manga - movie - podcast - show - videoGame - visualNovel - people - groups - genres - } - } - } + userPreferences { + general { + reviewScale + gridPacking + displayNsfw + disableVideos + persistQueries + disableReviews + disableIntegrations + disableWatchProviders + disableNavigationAnimation + dashboard { + section + hidden + numElements + } + watchProviders { + lot + values + } + } + fitness { + measurements { + custom { + name + dataType + } + inbuilt { + weight + bodyMassIndex + totalBodyWater + muscle + leanBodyMass + bodyFat + boneMass + visceralFat + waistCircumference + waistToHeightRatio + hipCircumference + waistToHipRatio + chestCircumference + thighCircumference + bicepsCircumference + neckCircumference + bodyFatCaliper + chestSkinfold + abdominalSkinfold + thighSkinfold + basalMetabolicRate + totalDailyEnergyExpenditure + calories + } + } + exercises { + unitSystem + setRestTimers { + ...SetRestTimersPart + } + } + } + notifications { + toSend + enabled + } + featuresEnabled { + others { + calendar + collections + } + fitness { + enabled + workouts + templates + measurements + } + media { + enabled + anime + audioBook + book + manga + movie + podcast + show + videoGame + visualNovel + people + groups + genres + } + } + } } diff --git a/libs/graphql/src/backend/queries/UserWorkoutDetails.gql b/libs/graphql/src/backend/queries/UserWorkoutDetails.gql index b50f704563..bbd2a383aa 100644 --- a/libs/graphql/src/backend/queries/UserWorkoutDetails.gql +++ b/libs/graphql/src/backend/queries/UserWorkoutDetails.gql @@ -1,22 +1,22 @@ query UserWorkoutDetails($workoutId: String!) { - userWorkoutDetails(workoutId: $workoutId) { - collections { - ...CollectionPart - } - details { - id - name - endTime - duration - startTime - templateId - repeatedFrom - summary { - ...WorkoutSummaryPart - } - information { - ...WorkoutInformationPart - } - } - } + userWorkoutDetails(workoutId: $workoutId) { + collections { + ...CollectionPart + } + details { + id + name + endTime + duration + startTime + templateId + repeatedFrom + summary { + ...WorkoutSummaryPart + } + information { + ...WorkoutInformationPart + } + } + } } diff --git a/libs/graphql/src/backend/queries/UserWorkoutTemplateDetails.gql b/libs/graphql/src/backend/queries/UserWorkoutTemplateDetails.gql index a6b9fbc27b..7b51652335 100644 --- a/libs/graphql/src/backend/queries/UserWorkoutTemplateDetails.gql +++ b/libs/graphql/src/backend/queries/UserWorkoutTemplateDetails.gql @@ -1,19 +1,19 @@ query UserWorkoutTemplateDetails($workoutTemplateId: String!) { - userWorkoutTemplateDetails(workoutTemplateId: $workoutTemplateId) { - collections { - ...CollectionPart - } - details { - id - name - createdOn - visibility - summary { - ...WorkoutSummaryPart - } - information { - ...WorkoutInformationPart - } - } - } + userWorkoutTemplateDetails(workoutTemplateId: $workoutTemplateId) { + collections { + ...CollectionPart + } + details { + id + name + createdOn + visibility + summary { + ...WorkoutSummaryPart + } + information { + ...WorkoutInformationPart + } + } + } } diff --git a/libs/graphql/src/backend/queries/UserWorkoutTemplatesList.gql b/libs/graphql/src/backend/queries/UserWorkoutTemplatesList.gql index 30a6c13583..8185202772 100644 --- a/libs/graphql/src/backend/queries/UserWorkoutTemplatesList.gql +++ b/libs/graphql/src/backend/queries/UserWorkoutTemplatesList.gql @@ -1,17 +1,17 @@ query UserWorkoutTemplatesList($input: SearchInput!) { - userWorkoutTemplatesList(input: $input) { - details { - total - nextPage - } - items { - id - name - createdOn - visibility - summary { - ...WorkoutSummaryPart - } - } - } + userWorkoutTemplatesList(input: $input) { + details { + total + nextPage + } + items { + id + name + createdOn + visibility + summary { + ...WorkoutSummaryPart + } + } + } } diff --git a/libs/graphql/src/backend/queries/UserWorkoutsList.gql b/libs/graphql/src/backend/queries/UserWorkoutsList.gql index 941df44c3f..ccb4e1b1d3 100644 --- a/libs/graphql/src/backend/queries/UserWorkoutsList.gql +++ b/libs/graphql/src/backend/queries/UserWorkoutsList.gql @@ -1,18 +1,18 @@ query UserWorkoutsList($input: SearchInput!) { - userWorkoutsList(input: $input) { - details { - total - nextPage - } - items { - id - name - endTime - duration - startTime - summary { - ...WorkoutSummaryPart - } - } - } + userWorkoutsList(input: $input) { + details { + total + nextPage + } + items { + id + name + endTime + duration + startTime + summary { + ...WorkoutSummaryPart + } + } + } } diff --git a/libs/graphql/src/backend/queries/combined.gql b/libs/graphql/src/backend/queries/combined.gql index be673a7b59..79b55d6e35 100644 --- a/libs/graphql/src/backend/queries/combined.gql +++ b/libs/graphql/src/backend/queries/combined.gql @@ -1,180 +1,180 @@ query GetOidcRedirectUrl { - getOidcRedirectUrl + getOidcRedirectUrl } query UserByOidcIssuerId($oidcIssuerId: String!) { - userByOidcIssuerId(oidcIssuerId: $oidcIssuerId) + userByOidcIssuerId(oidcIssuerId: $oidcIssuerId) } query GetOidcToken($code: String!) { - getOidcToken(code: $code) { - subject - email - } + getOidcToken(code: $code) { + subject + email + } } query GetPresignedS3Url($key: String!) { - getPresignedS3Url(key: $key) + getPresignedS3Url(key: $key) } query ProvidersLanguageInformation { - providersLanguageInformation { - supported - default - source - } + providersLanguageInformation { + supported + default + source + } } query UserExports { - userExports { - url - size - endedAt - startedAt - } + userExports { + url + size + endedAt + startedAt + } } query UserCollectionsList($name: String) { - userCollectionsList(name: $name) { - id - name - count - isDefault - description - creator { - id - name - } - collaborators { - id - name - } - informationTemplate { - lot - name - required - description - defaultValue - } - } + userCollectionsList(name: $name) { + id + name + count + isDefault + description + creator { + id + name + } + collaborators { + id + name + } + informationTemplate { + lot + name + required + description + defaultValue + } + } } query UserIntegrations { - userIntegrations { - id - lot - provider - createdOn - isDisabled - maximumProgress - minimumProgress - lastTriggeredOn - syncToOwnedCollection - } + userIntegrations { + id + lot + provider + createdOn + isDisabled + maximumProgress + minimumProgress + lastTriggeredOn + syncToOwnedCollection + } } query UserNotificationPlatforms { - userNotificationPlatforms { - id - lot - createdOn - isDisabled - description - } + userNotificationPlatforms { + id + lot + createdOn + isDisabled + description + } } query UsersList($query: String) { - usersList(query: $query) { - id - lot - name - isDisabled - } + usersList(query: $query) { + id + lot + name + isDisabled + } } query UserRecommendations { - userRecommendations + userRecommendations } query UserUpcomingCalendarEvents($input: UserUpcomingCalendarEventInput!) { - userUpcomingCalendarEvents(input: $input) { - ...CalendarEventPart - } + userUpcomingCalendarEvents(input: $input) { + ...CalendarEventPart + } } query UserCalendarEvents($input: UserCalendarEventInput!) { - userCalendarEvents(input: $input) { - date - events { - ...CalendarEventPart - } - } + userCalendarEvents(input: $input) { + date + events { + ...CalendarEventPart + } + } } query MetadataPartialDetails($metadataId: String!) { - metadataPartialDetails(metadataId: $metadataId) { - id - lot - title - image - publishYear - } + metadataPartialDetails(metadataId: $metadataId) { + id + lot + title + image + publishYear + } } query MetadataGroupsList($input: MetadataGroupsListInput!) { - metadataGroupsList(input: $input) { - details { - total - nextPage - } - items - } + metadataGroupsList(input: $input) { + details { + total + nextPage + } + items + } } query PeopleList($input: PeopleListInput!) { - peopleList(input: $input) { - details { - total - nextPage - } - items - } + peopleList(input: $input) { + details { + total + nextPage + } + items + } } query UserAccessLinks { - userAccessLinks { - id - name - isDemo - createdOn - expiresOn - timesUsed - isRevoked - maximumUses - isAccountDefault - isMutationAllowed - } + userAccessLinks { + id + name + isDemo + createdOn + expiresOn + timesUsed + isRevoked + maximumUses + isAccountDefault + isMutationAllowed + } } query DailyUserActivities($input: DailyUserActivitiesInput!) { - dailyUserActivities(input: $input) { - groupedBy - totalCount - totalDuration - items { - day - totalReviewCount - workoutCount - measurementCount - audioBookCount - animeCount - bookCount - podcastCount - mangaCount - showCount - movieCount - videoGameCount - visualNovelCount - } - } + dailyUserActivities(input: $input) { + groupedBy + totalCount + totalDuration + items { + day + totalReviewCount + workoutCount + measurementCount + audioBookCount + animeCount + bookCount + podcastCount + mangaCount + showCount + movieCount + videoGameCount + visualNovelCount + } + } } diff --git a/libs/graphql/src/backend/queries/fragments.gql b/libs/graphql/src/backend/queries/fragments.gql index 2eee276e82..f253e8beab 100644 --- a/libs/graphql/src/backend/queries/fragments.gql +++ b/libs/graphql/src/backend/queries/fragments.gql @@ -1,196 +1,196 @@ fragment SeenPodcastExtraInformationPart on SeenPodcastExtraInformation { - episode + episode } fragment SeenShowExtraInformationPart on SeenShowExtraInformation { - episode - season + episode + season } fragment SeenAnimeExtraInformationPart on SeenAnimeExtraInformation { - episode + episode } fragment SeenMangaExtraInformationPart on SeenMangaExtraInformation { - volume - chapter + volume + chapter } fragment CalendarEventPart on GraphqlCalendarEvent { - date - metadataId - metadataLot - episodeName - metadataTitle - metadataImage - calendarEventId - showExtraInformation { - ...SeenShowExtraInformationPart - } - podcastExtraInformation { - ...SeenPodcastExtraInformationPart - } - animeExtraInformation { - ...SeenAnimeExtraInformationPart - } + date + metadataId + metadataLot + episodeName + metadataTitle + metadataImage + calendarEventId + showExtraInformation { + ...SeenShowExtraInformationPart + } + podcastExtraInformation { + ...SeenPodcastExtraInformationPart + } + animeExtraInformation { + ...SeenAnimeExtraInformationPart + } } fragment SeenPart on Seen { - id - state - progress - reviewId - startedOn - finishedOn - lastUpdatedOn - manualTimeSpent - numTimesUpdated - providerWatchedOn - showExtraInformation { - ...SeenShowExtraInformationPart - } - podcastExtraInformation { - ...SeenPodcastExtraInformationPart - } - animeExtraInformation { - ...SeenAnimeExtraInformationPart - } - mangaExtraInformation { - ...SeenMangaExtraInformationPart - } + id + state + progress + reviewId + startedOn + finishedOn + lastUpdatedOn + manualTimeSpent + numTimesUpdated + providerWatchedOn + showExtraInformation { + ...SeenShowExtraInformationPart + } + podcastExtraInformation { + ...SeenPodcastExtraInformationPart + } + animeExtraInformation { + ...SeenAnimeExtraInformationPart + } + mangaExtraInformation { + ...SeenMangaExtraInformationPart + } } fragment MetadataSearchItemPart on MetadataSearchItem { - title - image - identifier - publishYear + title + image + identifier + publishYear } fragment WorkoutOrExerciseTotalsPart on WorkoutOrExerciseTotals { - reps - weight - distance - duration - restTime - personalBestsAchieved + reps + weight + distance + duration + restTime + personalBestsAchieved } fragment EntityAssetsPart on EntityAssets { - images - videos + images + videos } fragment WorkoutSetStatisticPart on WorkoutSetStatistic { - reps - pace - oneRm - weight - volume - duration - distance + reps + pace + oneRm + weight + volume + duration + distance } fragment WorkoutSetRecordPart on WorkoutSetRecord { - lot - personalBests - statistic { - ...WorkoutSetStatisticPart - } + lot + personalBests + statistic { + ...WorkoutSetStatisticPart + } } fragment WorkoutSummaryPart on WorkoutSummary { - total { - ...WorkoutOrExerciseTotalsPart - } - exercises { - lot - name - numSets - bestSet { - ...WorkoutSetRecordPart - } - } + total { + ...WorkoutOrExerciseTotalsPart + } + exercises { + lot + name + numSets + bestSet { + ...WorkoutSetRecordPart + } + } } fragment CollectionPart on Collection { - id - name - userId + id + name + userId } fragment ReviewItemPart on ReviewItem { - id - rating - postedOn - isSpoiler - visibility - textOriginal - textRendered - seenItemsAssociatedWith - postedBy { - id - name - } - comments { - id - text - likedBy - createdOn - user { - id - name - } - } - showExtraInformation { - ...SeenShowExtraInformationPart - } - podcastExtraInformation { - ...SeenPodcastExtraInformationPart - } - animeExtraInformation { - ...SeenAnimeExtraInformationPart - } - mangaExtraInformation { - ...SeenMangaExtraInformationPart - } + id + rating + postedOn + isSpoiler + visibility + textOriginal + textRendered + seenItemsAssociatedWith + postedBy { + id + name + } + comments { + id + text + likedBy + createdOn + user { + id + name + } + } + showExtraInformation { + ...SeenShowExtraInformationPart + } + podcastExtraInformation { + ...SeenPodcastExtraInformationPart + } + animeExtraInformation { + ...SeenAnimeExtraInformationPart + } + mangaExtraInformation { + ...SeenMangaExtraInformationPart + } } fragment WorkoutInformationPart on WorkoutInformation { - comment - assets { - ...EntityAssetsPart - } - supersets { - color - exercises - } - exercises { - lot - name - notes - total { - ...WorkoutOrExerciseTotalsPart - } - assets { - ...EntityAssetsPart - } - sets { - lot - note - restTime - confirmedAt - personalBests - statistic { - ...WorkoutSetStatisticPart - } - } - } + comment + assets { + ...EntityAssetsPart + } + supersets { + color + exercises + } + exercises { + lot + name + notes + total { + ...WorkoutOrExerciseTotalsPart + } + assets { + ...EntityAssetsPart + } + sets { + lot + note + restTime + confirmedAt + personalBests + statistic { + ...WorkoutSetStatisticPart + } + } + } } fragment SetRestTimersPart on SetRestTimersSettings { - drop - warmup - normal - failure + drop + warmup + normal + failure } diff --git a/libs/transactional/package.json b/libs/transactional/package.json index 14e7734301..e2ca63d46d 100644 --- a/libs/transactional/package.json +++ b/libs/transactional/package.json @@ -4,7 +4,12 @@ "dependencies": { "@react-email/components": "0.0.22", "@ryot/ts-utils": "workspace:*", + "react": "18.3.1", "react-dom": "18.3.1", "react-email": "2.1.6" + }, + "devDependencies": { + "@types/react": "18.3.11", + "@types/react-dom": "18.3.1" } } diff --git a/libs/ts-utils/package.json b/libs/ts-utils/package.json index 1f4ccdff0d..55feea8f15 100644 --- a/libs/ts-utils/package.json +++ b/libs/ts-utils/package.json @@ -2,13 +2,14 @@ "name": "@ryot/ts-utils", "main": "src/index.ts", "dependencies": { - "@conform-to/zod": "1.1.5", + "@conform-to/zod": "1.2.2", "@ryot/generated": "workspace:*", "dayjs": "1.11.13", "humanize-duration-ts": "2.1.1", - "lodash": "4.17.21" + "lodash": "4.17.21", + "tiny-invariant": "1.3.3" }, "devDependencies": { - "@types/lodash": "4.17.7" + "@types/lodash": "4.17.12" } } diff --git a/libs/ts-utils/src/index.ts b/libs/ts-utils/src/index.ts index 0070c57e1d..6b3a10f0c8 100644 --- a/libs/ts-utils/src/index.ts +++ b/libs/ts-utils/src/index.ts @@ -25,6 +25,7 @@ import sortBy from "lodash/sortBy"; import startCase from "lodash/startCase"; import sum from "lodash/sum"; import truncate from "lodash/truncate"; +import invariant from "tiny-invariant"; import type { ZodTypeAny, output } from "zod"; /** @@ -94,6 +95,13 @@ export const processSubmission = ( return submission.value; }; +export const getActionIntent = (request: Request) => { + const url = new URL(request.url); + const intent = url.searchParams.get("intent"); + invariant(intent); + return intent; +}; + export { camelCase, cloneDeep, diff --git a/package.json b/package.json index d7641da1af..e67dbbdc90 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,9 @@ "node": "20.10.0" }, "devDependencies": { - "@biomejs/biome": "1.8.3", + "@biomejs/biome": "1.9.4", "tsconfig-moon": "1.3.0", - "typescript": "5.5.4" + "typescript": "5.6.3" }, "resolutions": { "@types/react": "18.3.4" diff --git a/yarn.lock b/yarn.lock index f437cc8af9..2d77a6599e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1472,12 +1472,12 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.9.2": - version: 7.23.1 - resolution: "@babel/runtime@npm:7.23.1" +"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.23.5, @babel/runtime@npm:^7.25.6": + version: 7.25.9 + resolution: "@babel/runtime@npm:7.25.9" dependencies: regenerator-runtime: "npm:^0.14.0" - checksum: 10/a9fdd322ae1f5d5e3446b6181745300f863164a30acb35ee296c6989cf0ecfd57598a7a6ef209b414575cabe81ef17756412052b3d85fcaf8729332b5b70c45f + checksum: 10/8d904cfcb433374b3bb90369452751c94ae69547cdd3679950de4527ac5d04195b9c4a1840482a6f3a84694cb22a6403a7f98b826d60cd945918223a4a6b479c languageName: node linkType: hard @@ -1490,7 +1490,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.21.0": +"@babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.18.3": version: 7.25.6 resolution: "@babel/runtime@npm:7.25.6" dependencies: @@ -1499,21 +1499,12 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.23.5": - version: 7.24.8 - resolution: "@babel/runtime@npm:7.24.8" - dependencies: - regenerator-runtime: "npm:^0.14.0" - checksum: 10/e6f335e472a8a337379effc15815dd0eddf6a7d0c00b50deb4f9e9585819b45431d0ff3c2d3d0fa58c227a9b04dcc4a85e7245fb57493adb2863b5208c769cbd - languageName: node - linkType: hard - -"@babel/runtime@npm:^7.24.1": - version: 7.24.4 - resolution: "@babel/runtime@npm:7.24.4" +"@babel/runtime@npm:^7.20.13": + version: 7.23.1 + resolution: "@babel/runtime@npm:7.23.1" dependencies: regenerator-runtime: "npm:^0.14.0" - checksum: 10/8ec8ce2c145bc7e31dd39ab66df124f357f65c11489aefacb30f431bae913b9aaa66aa5efe5321ea2bf8878af3fcee338c87e7599519a952e3a6f83aa1b03308 + checksum: 10/a9fdd322ae1f5d5e3446b6181745300f863164a30acb35ee296c6989cf0ecfd57598a7a6ef209b414575cabe81ef17756412052b3d85fcaf8729332b5b70c45f languageName: node linkType: hard @@ -1736,18 +1727,18 @@ __metadata: languageName: node linkType: hard -"@biomejs/biome@npm:1.8.3": - version: 1.8.3 - resolution: "@biomejs/biome@npm:1.8.3" +"@biomejs/biome@npm:1.9.4": + version: 1.9.4 + resolution: "@biomejs/biome@npm:1.9.4" dependencies: - "@biomejs/cli-darwin-arm64": "npm:1.8.3" - "@biomejs/cli-darwin-x64": "npm:1.8.3" - "@biomejs/cli-linux-arm64": "npm:1.8.3" - "@biomejs/cli-linux-arm64-musl": "npm:1.8.3" - "@biomejs/cli-linux-x64": "npm:1.8.3" - "@biomejs/cli-linux-x64-musl": "npm:1.8.3" - "@biomejs/cli-win32-arm64": "npm:1.8.3" - "@biomejs/cli-win32-x64": "npm:1.8.3" + "@biomejs/cli-darwin-arm64": "npm:1.9.4" + "@biomejs/cli-darwin-x64": "npm:1.9.4" + "@biomejs/cli-linux-arm64": "npm:1.9.4" + "@biomejs/cli-linux-arm64-musl": "npm:1.9.4" + "@biomejs/cli-linux-x64": "npm:1.9.4" + "@biomejs/cli-linux-x64-musl": "npm:1.9.4" + "@biomejs/cli-win32-arm64": "npm:1.9.4" + "@biomejs/cli-win32-x64": "npm:1.9.4" dependenciesMeta: "@biomejs/cli-darwin-arm64": optional: true @@ -1767,62 +1758,62 @@ __metadata: optional: true bin: biome: bin/biome - checksum: 10/62dfa5147712ef21c384ea7b3c93c0ccac58291a85f2bbd2dee22c8381da5e347cd07bdb7bfcafcecb07fc112349e9d101e697774155553bde987fd47f9b12a1 + checksum: 10/bd8ff8fb4dc0581bd60a9b9ac28d0cd03ba17c6a1de2ab6228b7fda582079594ceee774f47e41aac2fc6d35de1637def2e32ef2e58fa24e22d1b24ef9ee5cefa languageName: node linkType: hard -"@biomejs/cli-darwin-arm64@npm:1.8.3": - version: 1.8.3 - resolution: "@biomejs/cli-darwin-arm64@npm:1.8.3" +"@biomejs/cli-darwin-arm64@npm:1.9.4": + version: 1.9.4 + resolution: "@biomejs/cli-darwin-arm64@npm:1.9.4" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@biomejs/cli-darwin-x64@npm:1.8.3": - version: 1.8.3 - resolution: "@biomejs/cli-darwin-x64@npm:1.8.3" +"@biomejs/cli-darwin-x64@npm:1.9.4": + version: 1.9.4 + resolution: "@biomejs/cli-darwin-x64@npm:1.9.4" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@biomejs/cli-linux-arm64-musl@npm:1.8.3": - version: 1.8.3 - resolution: "@biomejs/cli-linux-arm64-musl@npm:1.8.3" +"@biomejs/cli-linux-arm64-musl@npm:1.9.4": + version: 1.9.4 + resolution: "@biomejs/cli-linux-arm64-musl@npm:1.9.4" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@biomejs/cli-linux-arm64@npm:1.8.3": - version: 1.8.3 - resolution: "@biomejs/cli-linux-arm64@npm:1.8.3" +"@biomejs/cli-linux-arm64@npm:1.9.4": + version: 1.9.4 + resolution: "@biomejs/cli-linux-arm64@npm:1.9.4" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@biomejs/cli-linux-x64-musl@npm:1.8.3": - version: 1.8.3 - resolution: "@biomejs/cli-linux-x64-musl@npm:1.8.3" +"@biomejs/cli-linux-x64-musl@npm:1.9.4": + version: 1.9.4 + resolution: "@biomejs/cli-linux-x64-musl@npm:1.9.4" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@biomejs/cli-linux-x64@npm:1.8.3": - version: 1.8.3 - resolution: "@biomejs/cli-linux-x64@npm:1.8.3" +"@biomejs/cli-linux-x64@npm:1.9.4": + version: 1.9.4 + resolution: "@biomejs/cli-linux-x64@npm:1.9.4" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@biomejs/cli-win32-arm64@npm:1.8.3": - version: 1.8.3 - resolution: "@biomejs/cli-win32-arm64@npm:1.8.3" +"@biomejs/cli-win32-arm64@npm:1.9.4": + version: 1.9.4 + resolution: "@biomejs/cli-win32-arm64@npm:1.9.4" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@biomejs/cli-win32-x64@npm:1.8.3": - version: 1.8.3 - resolution: "@biomejs/cli-win32-x64@npm:1.8.3" +"@biomejs/cli-win32-x64@npm:1.9.4": + version: 1.9.4 + resolution: "@biomejs/cli-win32-x64@npm:1.9.4" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -1836,32 +1827,56 @@ __metadata: languageName: node linkType: hard -"@conform-to/dom@npm:1.1.5": - version: 1.1.5 - resolution: "@conform-to/dom@npm:1.1.5" - checksum: 10/2b5a7d3aedde7e426e9befbf1ef9bc2103e141e80b3a6bf2bd4ebe51bcdaea6aed61fcb2b84ebd3d094822fd3df6a09c256726b3608edd1b903bb47599b0023f +"@bkrem/react-transition-group@npm:^1.3.3": + version: 1.3.3 + resolution: "@bkrem/react-transition-group@npm:1.3.3" + dependencies: + chain-function: "npm:^1.0.0" + dom-helpers: "npm:^3.3.1" + loose-envify: "npm:^1.3.1" + prop-types: "npm:^15.5.6" + react-lifecycles-compat: "npm:^3.0.4" + warning: "npm:^3.0.0" + peerDependencies: + react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + checksum: 10/0263651a3f36f453a8fb1a9928e96c2b4d9329f02bbc3bcbf367cc27f7dbe3a1777b70e3e751eef7f1e9d3c962eb7e5dc3da0e9785d7f5651b309efdd4758762 languageName: node linkType: hard -"@conform-to/react@npm:1.1.5": - version: 1.1.5 - resolution: "@conform-to/react@npm:1.1.5" +"@conform-to/dom@npm:1.2.2": + version: 1.2.2 + resolution: "@conform-to/dom@npm:1.2.2" + checksum: 10/7276d53750b3cf631b14c14bbb009dec08e2008b9c47e4a7fa51ee938b8cd9ab90c9612d9376b4301c1ababda2a0ece48cb3a58104b4d59c37c622bf8f61f0c8 + languageName: node + linkType: hard + +"@conform-to/react@npm:1.2.2": + version: 1.2.2 + resolution: "@conform-to/react@npm:1.2.2" dependencies: - "@conform-to/dom": "npm:1.1.5" + "@conform-to/dom": "npm:1.2.2" peerDependencies: react: ">=18" - checksum: 10/04bcc830e2ea2ed54dc71a05d5b02368305a102496a4a4ad671d964030280f2a4aa731449ef28c51c044061c4155d8a0cb6fed8898bf217b75160cf5b3039ec0 + checksum: 10/966cceade7fda8019eccc3d0efb0e7525016a17f2fb44767c4a2d0870c47da3af81624ee51dabe88772654e99a7fa373b5345811654acd7c19e39300dfd7cb63 languageName: node linkType: hard -"@conform-to/zod@npm:1.1.5": - version: 1.1.5 - resolution: "@conform-to/zod@npm:1.1.5" +"@conform-to/zod@npm:1.2.2": + version: 1.2.2 + resolution: "@conform-to/zod@npm:1.2.2" dependencies: - "@conform-to/dom": "npm:1.1.5" + "@conform-to/dom": "npm:1.2.2" peerDependencies: zod: ^3.21.0 - checksum: 10/81abe866548445e1239c9905865fb4613a9a2db9d35f21a35d2e06962331d8bd431cea16f3f8ec570fd6c72620b72414cf0c97efee679441f94f29dad2cb8f88 + checksum: 10/1fbc452aeebe0d3a4b347637f83d871f13cd4b64fe1e8baed2b82f8f51eceee532b78eb369e278be0792671c1d9245a0c7c449056ea74150613bf8907b69c758 + languageName: node + linkType: hard + +"@drizzle-team/brocli@npm:^0.10.1": + version: 0.10.1 + resolution: "@drizzle-team/brocli@npm:0.10.1" + checksum: 10/4f14ca31b2fe3561cbf8e71e119fb6d7f78123f63b404ee631bbae2fc756eaf3eded222f30e70d92203ec0679b6ae8685183dbff9e9e8547e70fdcf608a66013 languageName: node linkType: hard @@ -2903,18 +2918,6 @@ __metadata: languageName: node linkType: hard -"@graphql-codegen/add@npm:^5.0.2": - version: 5.0.2 - resolution: "@graphql-codegen/add@npm:5.0.2" - dependencies: - "@graphql-codegen/plugin-helpers": "npm:^5.0.3" - tslib: "npm:~2.6.0" - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 10/60f32609d9e97ca2c48dc6fc4ff212c5e600e02c1cd583448a4fea01b9d24a9c75e70691ae56aabdd3d4c1e918825c8d813705300ca68047046f3a8cddc0c0c8 - languageName: node - linkType: hard - "@graphql-codegen/add@npm:^5.0.3": version: 5.0.3 resolution: "@graphql-codegen/add@npm:5.0.3" @@ -2927,14 +2930,14 @@ __metadata: languageName: node linkType: hard -"@graphql-codegen/cli@npm:5.0.2": - version: 5.0.2 - resolution: "@graphql-codegen/cli@npm:5.0.2" +"@graphql-codegen/cli@npm:5.0.3": + version: 5.0.3 + resolution: "@graphql-codegen/cli@npm:5.0.3" dependencies: "@babel/generator": "npm:^7.18.13" "@babel/template": "npm:^7.18.10" "@babel/types": "npm:^7.18.13" - "@graphql-codegen/client-preset": "npm:^4.2.2" + "@graphql-codegen/client-preset": "npm:^4.4.0" "@graphql-codegen/core": "npm:^4.0.2" "@graphql-codegen/plugin-helpers": "npm:^5.0.3" "@graphql-tools/apollo-engine-loader": "npm:^8.0.0" @@ -2947,12 +2950,12 @@ __metadata: "@graphql-tools/prisma-loader": "npm:^8.0.0" "@graphql-tools/url-loader": "npm:^8.0.0" "@graphql-tools/utils": "npm:^10.0.0" - "@whatwg-node/fetch": "npm:^0.8.0" + "@whatwg-node/fetch": "npm:^0.9.20" chalk: "npm:^4.1.0" cosmiconfig: "npm:^8.1.3" debounce: "npm:^1.2.0" detect-indent: "npm:^6.0.0" - graphql-config: "npm:^5.0.2" + graphql-config: "npm:^5.1.1" inquirer: "npm:^8.0.0" is-glob: "npm:^4.0.1" jiti: "npm:^1.17.1" @@ -2977,53 +2980,30 @@ __metadata: graphql-code-generator: cjs/bin.js graphql-codegen: cjs/bin.js graphql-codegen-esm: esm/bin.js - checksum: 10/24f5a4d441e4af2f0cae1818c8643a5400718cc1f08ca829a9110a35d99cb5529b567991ce826544b5a2aab36d0be3b10309dc112343bab1232d7c6f2fa14008 + checksum: 10/c3359668f824246e78656d26af506b5b279d50e08a56f54db87da492bd4d0a8e8b6540a6119402d7f5026c137babfd79e628897c6038e199ee6322f688eec757 languageName: node linkType: hard -"@graphql-codegen/client-preset@npm:4.3.3": - version: 4.3.3 - resolution: "@graphql-codegen/client-preset@npm:4.3.3" +"@graphql-codegen/client-preset@npm:4.4.0, @graphql-codegen/client-preset@npm:^4.4.0": + version: 4.4.0 + resolution: "@graphql-codegen/client-preset@npm:4.4.0" dependencies: "@babel/helper-plugin-utils": "npm:^7.20.2" "@babel/template": "npm:^7.20.7" "@graphql-codegen/add": "npm:^5.0.3" - "@graphql-codegen/gql-tag-operations": "npm:4.0.9" + "@graphql-codegen/gql-tag-operations": "npm:4.0.10" "@graphql-codegen/plugin-helpers": "npm:^5.0.4" - "@graphql-codegen/typed-document-node": "npm:^5.0.9" - "@graphql-codegen/typescript": "npm:^4.0.9" - "@graphql-codegen/typescript-operations": "npm:^4.2.3" - "@graphql-codegen/visitor-plugin-common": "npm:^5.3.1" - "@graphql-tools/documents": "npm:^1.0.0" - "@graphql-tools/utils": "npm:^10.0.0" - "@graphql-typed-document-node/core": "npm:3.2.0" - tslib: "npm:~2.6.0" - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 10/fd58f6d0bad4f687af84015a487e02f01c9cb4a1e310b59ceda48f872885e9dbe69e87271363bf51a805e7970169a121cd13b5df20b124d1d0054530dedbcf81 - languageName: node - linkType: hard - -"@graphql-codegen/client-preset@npm:^4.2.2": - version: 4.2.2 - resolution: "@graphql-codegen/client-preset@npm:4.2.2" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.20.2" - "@babel/template": "npm:^7.20.7" - "@graphql-codegen/add": "npm:^5.0.2" - "@graphql-codegen/gql-tag-operations": "npm:4.0.4" - "@graphql-codegen/plugin-helpers": "npm:^5.0.3" - "@graphql-codegen/typed-document-node": "npm:^5.0.4" - "@graphql-codegen/typescript": "npm:^4.0.4" - "@graphql-codegen/typescript-operations": "npm:^4.1.2" - "@graphql-codegen/visitor-plugin-common": "npm:^4.1.2" + "@graphql-codegen/typed-document-node": "npm:^5.0.10" + "@graphql-codegen/typescript": "npm:^4.1.0" + "@graphql-codegen/typescript-operations": "npm:^4.3.0" + "@graphql-codegen/visitor-plugin-common": "npm:^5.4.0" "@graphql-tools/documents": "npm:^1.0.0" "@graphql-tools/utils": "npm:^10.0.0" "@graphql-typed-document-node/core": "npm:3.2.0" tslib: "npm:~2.6.0" peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 10/85b167796b5e4665dc36bc9310880f5493a1b2c6b55985c6f056c97adfb9f3b353d425df348e7a5a027e3999efb5dff7a64c62f9dfb40134bf481248f087f53a + checksum: 10/f9cf01d61e26cf44f1a064977b3d5835755e72042d0dfdcd298d43c62ccc74b240d678d13625b11d93f0f825742c44324066f873568879faee0eb5499e7d9aa3 languageName: node linkType: hard @@ -3041,33 +3021,18 @@ __metadata: languageName: node linkType: hard -"@graphql-codegen/gql-tag-operations@npm:4.0.4": - version: 4.0.4 - resolution: "@graphql-codegen/gql-tag-operations@npm:4.0.4" - dependencies: - "@graphql-codegen/plugin-helpers": "npm:^5.0.3" - "@graphql-codegen/visitor-plugin-common": "npm:4.1.2" - "@graphql-tools/utils": "npm:^10.0.0" - auto-bind: "npm:~4.0.0" - tslib: "npm:~2.6.0" - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 10/d094b6c32568a0d4a3fee3f6c3f3997e28b2f42aaa6c0ba3d68e6fbfc1fce3c1ad68777d85700bbd4e53d5d67a52758db0c950d9ae213c04b318ddc66f99dc27 - languageName: node - linkType: hard - -"@graphql-codegen/gql-tag-operations@npm:4.0.9": - version: 4.0.9 - resolution: "@graphql-codegen/gql-tag-operations@npm:4.0.9" +"@graphql-codegen/gql-tag-operations@npm:4.0.10": + version: 4.0.10 + resolution: "@graphql-codegen/gql-tag-operations@npm:4.0.10" dependencies: "@graphql-codegen/plugin-helpers": "npm:^5.0.4" - "@graphql-codegen/visitor-plugin-common": "npm:5.3.1" + "@graphql-codegen/visitor-plugin-common": "npm:5.4.0" "@graphql-tools/utils": "npm:^10.0.0" auto-bind: "npm:~4.0.0" tslib: "npm:~2.6.0" peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 10/90eaecbe0742ee65f0e25df471760664d615bb6396d7e35c2d33615128849c1bdb1c0479c75de589479b7b1a0ee99b34684a2faeeff6245e01ffa7dcfff4b0c6 + checksum: 10/ff644cf5955a4706f245aea1313e276cc8d4346ad7b11371084977fb65c36b3c84538ef393d1f73b2cffa547ab7da0851b80f86f765de2bed07f228f82465593 languageName: node linkType: hard @@ -3116,119 +3081,54 @@ __metadata: languageName: node linkType: hard -"@graphql-codegen/typed-document-node@npm:^5.0.4": - version: 5.0.4 - resolution: "@graphql-codegen/typed-document-node@npm:5.0.4" - dependencies: - "@graphql-codegen/plugin-helpers": "npm:^5.0.3" - "@graphql-codegen/visitor-plugin-common": "npm:4.1.2" - auto-bind: "npm:~4.0.0" - change-case-all: "npm:1.0.15" - tslib: "npm:~2.6.0" - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 10/9f56c4fc59b1f1db09617fe3714bd42c6243856813fe8c5bfa7712c49e6ce9ddf39d3388a431f0690577048c59491f19d52c9640d8502b9c7f82f98fa08c0f0b - languageName: node - linkType: hard - -"@graphql-codegen/typed-document-node@npm:^5.0.9": - version: 5.0.9 - resolution: "@graphql-codegen/typed-document-node@npm:5.0.9" +"@graphql-codegen/typed-document-node@npm:^5.0.10": + version: 5.0.10 + resolution: "@graphql-codegen/typed-document-node@npm:5.0.10" dependencies: "@graphql-codegen/plugin-helpers": "npm:^5.0.4" - "@graphql-codegen/visitor-plugin-common": "npm:5.3.1" + "@graphql-codegen/visitor-plugin-common": "npm:5.4.0" auto-bind: "npm:~4.0.0" change-case-all: "npm:1.0.15" tslib: "npm:~2.6.0" peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 10/0cac39bf2d8304660dc99b46b9c6ed811be79aca8a2cd1f58d9a16ff83fb644e985d872456eed5fdba27fa1727e76c3d3190e251c0171d83aff1af58cbcbc3c8 - languageName: node - linkType: hard - -"@graphql-codegen/typescript-operations@npm:^4.1.2": - version: 4.1.2 - resolution: "@graphql-codegen/typescript-operations@npm:4.1.2" - dependencies: - "@graphql-codegen/plugin-helpers": "npm:^5.0.3" - "@graphql-codegen/typescript": "npm:^4.0.4" - "@graphql-codegen/visitor-plugin-common": "npm:4.1.2" - auto-bind: "npm:~4.0.0" - tslib: "npm:~2.6.0" - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 10/114a9f63d30977a7b55632e2ac18c3b3a095221c61b2976b400b8765c948db43eb5c98041c61b67852e155670da809c0e938411fb206d9212d86fda54f89d8f3 + checksum: 10/0aa3814359f75273971afb91e67aff30c4128fdd49f5dda1d6496ba061b3c24af0a9825238be6014a275f8fb65c97190611dd65eef126a82f666764d6b4d350a languageName: node linkType: hard -"@graphql-codegen/typescript-operations@npm:^4.2.3": - version: 4.2.3 - resolution: "@graphql-codegen/typescript-operations@npm:4.2.3" +"@graphql-codegen/typescript-operations@npm:^4.3.0": + version: 4.3.0 + resolution: "@graphql-codegen/typescript-operations@npm:4.3.0" dependencies: "@graphql-codegen/plugin-helpers": "npm:^5.0.4" - "@graphql-codegen/typescript": "npm:^4.0.9" - "@graphql-codegen/visitor-plugin-common": "npm:5.3.1" + "@graphql-codegen/typescript": "npm:^4.1.0" + "@graphql-codegen/visitor-plugin-common": "npm:5.4.0" auto-bind: "npm:~4.0.0" tslib: "npm:~2.6.0" peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 10/b501b43c5a686847e12812690e0aea3842c6efa10d53703db063d82f2a4f3c469bb02c430a29ac1d1b450ffc82cf97c0ca1b9caa8e8979279f72646f010301bf - languageName: node - linkType: hard - -"@graphql-codegen/typescript@npm:^4.0.4": - version: 4.0.4 - resolution: "@graphql-codegen/typescript@npm:4.0.4" - dependencies: - "@graphql-codegen/plugin-helpers": "npm:^5.0.3" - "@graphql-codegen/schema-ast": "npm:^4.0.2" - "@graphql-codegen/visitor-plugin-common": "npm:4.1.2" - auto-bind: "npm:~4.0.0" - tslib: "npm:~2.6.0" - peerDependencies: - graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 10/0f451fd6fc13ef486fc80f74d3489d8de45e7c69ee684e9fbae441c2b0d70560f3139db4ff2c179cd10277c5375cb8e24d52234ec11fa19fde1855c21e6e3819 + checksum: 10/0c178d7bd72284359aab0e523d2033cfa4ee4ebe1c0ff2c98b41a0fd09c5396e7f8a1e51f1f39374e0d29a5445193047f2da383230ae1ac1a6b41fefa53d8fac languageName: node linkType: hard -"@graphql-codegen/typescript@npm:^4.0.9": - version: 4.0.9 - resolution: "@graphql-codegen/typescript@npm:4.0.9" +"@graphql-codegen/typescript@npm:^4.1.0": + version: 4.1.0 + resolution: "@graphql-codegen/typescript@npm:4.1.0" dependencies: "@graphql-codegen/plugin-helpers": "npm:^5.0.4" "@graphql-codegen/schema-ast": "npm:^4.0.2" - "@graphql-codegen/visitor-plugin-common": "npm:5.3.1" + "@graphql-codegen/visitor-plugin-common": "npm:5.4.0" auto-bind: "npm:~4.0.0" tslib: "npm:~2.6.0" peerDependencies: graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 10/304026adfe622530b8a2827569dd5bbd390177051be8c214fb79873ec64ef21793635c91657703bfd229a3d06f1a8a6f1addd8ae7eab20d1eff2efe6fb044df7 - languageName: node - linkType: hard - -"@graphql-codegen/visitor-plugin-common@npm:4.1.2, @graphql-codegen/visitor-plugin-common@npm:^4.1.2": - version: 4.1.2 - resolution: "@graphql-codegen/visitor-plugin-common@npm:4.1.2" - dependencies: - "@graphql-codegen/plugin-helpers": "npm:^5.0.3" - "@graphql-tools/optimize": "npm:^2.0.0" - "@graphql-tools/relay-operation-optimizer": "npm:^7.0.0" - "@graphql-tools/utils": "npm:^10.0.0" - auto-bind: "npm:~4.0.0" - change-case-all: "npm:1.0.15" - dependency-graph: "npm:^0.11.0" - graphql-tag: "npm:^2.11.0" - parse-filepath: "npm:^1.0.2" - tslib: "npm:~2.6.0" - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 10/a852d88b401161f650700f731d63743d191a375a9b77e49c117d0884b0a3d4c109332d00b393711039de5c1586ad2810c30dd46450d4d0d1eac6336c34138bfe + checksum: 10/e18bebd494fcfd9f76b1bdb4cbf75ae4de5fc9bc87a675eae0859c5ad3d073c9ae1d8452819a2e404e281602c44dcbb03659725c3949ae6829cc99c138edf96c languageName: node linkType: hard -"@graphql-codegen/visitor-plugin-common@npm:5.3.1, @graphql-codegen/visitor-plugin-common@npm:^5.3.1": - version: 5.3.1 - resolution: "@graphql-codegen/visitor-plugin-common@npm:5.3.1" +"@graphql-codegen/visitor-plugin-common@npm:5.4.0, @graphql-codegen/visitor-plugin-common@npm:^5.4.0": + version: 5.4.0 + resolution: "@graphql-codegen/visitor-plugin-common@npm:5.4.0" dependencies: "@graphql-codegen/plugin-helpers": "npm:^5.0.4" "@graphql-tools/optimize": "npm:^2.0.0" @@ -3242,7 +3142,7 @@ __metadata: tslib: "npm:~2.6.0" peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 10/6dd0464d9099d5aeabeb766515fc8dd2fc84bcae4cb0e3653d7f38aea716d6622d35d7cbb57a1954e6bc1cde10f4dd8c4a75ceb4e8bb8cdbba16219615666a5f + checksum: 10/cbfa918b6a5ee5ab4c5edf0af53adaf5b4bbc5e7a0a1355fd0736ec859a9b41f4d5313489d6fa13963dc7d5724ff16f1c00c2f31ffe2b7f201a74a900ad818f9 languageName: node linkType: hard @@ -3624,21 +3524,21 @@ __metadata: languageName: node linkType: hard -"@hello-pangea/dnd@npm:16.6.0": - version: 16.6.0 - resolution: "@hello-pangea/dnd@npm:16.6.0" +"@hello-pangea/dnd@npm:17.0.0": + version: 17.0.0 + resolution: "@hello-pangea/dnd@npm:17.0.0" dependencies: - "@babel/runtime": "npm:^7.24.1" + "@babel/runtime": "npm:^7.25.6" css-box-model: "npm:^1.2.1" memoize-one: "npm:^6.0.0" raf-schd: "npm:^4.0.3" - react-redux: "npm:^8.1.3" - redux: "npm:^4.2.1" + react-redux: "npm:^9.1.2" + redux: "npm:^5.0.1" use-memo-one: "npm:^1.1.3" peerDependencies: - react: ^16.8.5 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.5 || ^17.0.0 || ^18.0.0 - checksum: 10/f377461d400c8223174745e4d7ecf4fb0146f9e807413f98120ebbcf075282e631273988d336daaf1fb8e6b6c6a1a8e4f99beefecd7a6b68ccc3bb064d38f13f + react: ^18.0.0 + react-dom: ^18.0.0 + checksum: 10/4795063e249a818c60e223f3527797878cb546ef007a52a7dd6c1a01094d3b2107820476a10fc83c0ba9dc4387c1ae49e70c8f8cff9722636219773caad19372 languageName: node linkType: hard @@ -3771,6 +3671,13 @@ __metadata: languageName: node linkType: hard +"@kamilkisiela/fast-url-parser@npm:^1.1.4": + version: 1.1.4 + resolution: "@kamilkisiela/fast-url-parser@npm:1.1.4" + checksum: 10/5b79438235a81817b02b96ddc581c996961cec5b40c7d6ebabd01ac6af8d4a35a43b9b263144af25386cef92c054c3ef6b1723b09eb0d8cf7b4053781a474c5f + languageName: node + linkType: hard + "@lukemorales/query-key-factory@npm:1.3.4": version: 1.3.4 resolution: "@lukemorales/query-key-factory@npm:1.3.4" @@ -3781,35 +3688,35 @@ __metadata: languageName: node linkType: hard -"@mantine/carousel@npm:7.12.1": - version: 7.12.1 - resolution: "@mantine/carousel@npm:7.12.1" +"@mantine/carousel@npm:7.13.3": + version: 7.13.3 + resolution: "@mantine/carousel@npm:7.13.3" peerDependencies: - "@mantine/core": 7.12.1 - "@mantine/hooks": 7.12.1 + "@mantine/core": 7.13.3 + "@mantine/hooks": 7.13.3 embla-carousel-react: ">=7.0.0" react: ^18.2.0 react-dom: ^18.2.0 - checksum: 10/a46c9dc9ad09c3235574a4517fea00c9727a2af2629a47f48cf9f884c8dc7282a4837f41227864b941c63622235bed03da175a5ab80a5ad3ac20f4a2b2635fd4 + checksum: 10/1fef3f47ee4a35877c39514df8fb8c6bb8a23132d3fb6d2a6939f454eda82d0abb4d0b6cc2c42353695fb49d8dc093b18c1edfbf9e551de7592c61e463dbf1a9 languageName: node linkType: hard -"@mantine/charts@npm:7.12.1": - version: 7.12.1 - resolution: "@mantine/charts@npm:7.12.1" +"@mantine/charts@npm:7.13.3": + version: 7.13.3 + resolution: "@mantine/charts@npm:7.13.3" peerDependencies: - "@mantine/core": 7.12.1 - "@mantine/hooks": 7.12.1 + "@mantine/core": 7.13.3 + "@mantine/hooks": 7.13.3 react: ^18.2.0 react-dom: ^18.2.0 recharts: ^2.10.3 - checksum: 10/c38b5cb1f3925d452cf02ab6cef946e6a645f0e102a1eafe39072d84461c7713efc11089b094323db5b491475b1cdcd4fb1d821cd0b76b9f5dab26dfe013a42f + checksum: 10/55681425074251f45b4892586c60146909eae3f6d86e543dbec1fd771a2bb286f2027baa9f6d5f048da522b162c00dfd41d6809275f69cdb8175886836035916 languageName: node linkType: hard -"@mantine/core@npm:7.12.1": - version: 7.12.1 - resolution: "@mantine/core@npm:7.12.1" +"@mantine/core@npm:7.13.3": + version: 7.13.3 + resolution: "@mantine/core@npm:7.13.3" dependencies: "@floating-ui/react": "npm:^0.26.9" clsx: "npm:^2.1.1" @@ -3818,70 +3725,70 @@ __metadata: react-textarea-autosize: "npm:8.5.3" type-fest: "npm:^4.12.0" peerDependencies: - "@mantine/hooks": 7.12.1 + "@mantine/hooks": 7.13.3 react: ^18.2.0 react-dom: ^18.2.0 - checksum: 10/c90c9496b06dcef4e969659bb4ff281175dda26faa091cf4a684c99c7eedcf59b749f570c361a3ffeb6f85b923087d1cc037bc4944ff34f453ea595eb205ea18 + checksum: 10/db53ae05c80f7d05f5eae78df30e5398c4a5c3594fdaadb3d6260227be3557b89ce671e8bb5db6e9a5f6c410bdad76199cd833d1406f4b97e7cabe14f552bb30 languageName: node linkType: hard -"@mantine/dates@npm:7.12.1": - version: 7.12.1 - resolution: "@mantine/dates@npm:7.12.1" +"@mantine/dates@npm:7.13.3": + version: 7.13.3 + resolution: "@mantine/dates@npm:7.13.3" dependencies: clsx: "npm:^2.1.1" peerDependencies: - "@mantine/core": 7.12.1 - "@mantine/hooks": 7.12.1 + "@mantine/core": 7.13.3 + "@mantine/hooks": 7.13.3 dayjs: ">=1.0.0" react: ^18.2.0 react-dom: ^18.2.0 - checksum: 10/b019c24dfdd316fbc58223ddbce34236fde8e6c40eacd3ec725082a10cbec094ffec3e9d4e95a71cc7c564e8222178443ae2aacaabfe1d21b4769463b156f159 + checksum: 10/b7b9057471003908898e89d6be36f1058d138a052b0f4a93ca6fd5c4fc5bd7f04133a7cc1214db367802219bf36495153690674e5dca3d37bc0be934c47c71c1 languageName: node linkType: hard -"@mantine/form@npm:7.12.1": - version: 7.12.1 - resolution: "@mantine/form@npm:7.12.1" +"@mantine/form@npm:7.13.3": + version: 7.13.3 + resolution: "@mantine/form@npm:7.13.3" dependencies: fast-deep-equal: "npm:^3.1.3" klona: "npm:^2.0.6" peerDependencies: react: ^18.2.0 - checksum: 10/8832579175a8c443c2a92ea9d362e63c27540ad7403a4281241e7a9f378bc0a1f67d70b28f8b0eb21c2bcce56b5b66cf0ea8eb4509f893ac976685c8bb9c4574 + checksum: 10/34312932855103888ebe9be99c8ddf379691aa9d0ba0cc75e97289c4d20154a9367e228e0e3f5e22fffecec645b57343f5e7906be2ea29e5918561bf12484e77 languageName: node linkType: hard -"@mantine/hooks@npm:7.12.1": - version: 7.12.1 - resolution: "@mantine/hooks@npm:7.12.1" +"@mantine/hooks@npm:7.13.3": + version: 7.13.3 + resolution: "@mantine/hooks@npm:7.13.3" peerDependencies: react: ^18.2.0 - checksum: 10/ea00e49028f04f30678173a78048e4fd97ae4c8fbc32cf1b422e3f6b5fdc72c388ed5a9a7ae6169906b0c9b6bd662beb53d84ed0d665771f6b1ed1bab0c569c1 + checksum: 10/720a121f746c009952e0fc606918347f6071a548325358c65bb88bf2071eb6c5cdbebc2c2e4f2ac3324c8116525490c7d169c52ce62ac6d56022edf0e2d4f1ab languageName: node linkType: hard -"@mantine/notifications@npm:7.12.1": - version: 7.12.1 - resolution: "@mantine/notifications@npm:7.12.1" +"@mantine/notifications@npm:7.13.3": + version: 7.13.3 + resolution: "@mantine/notifications@npm:7.13.3" dependencies: - "@mantine/store": "npm:7.12.1" + "@mantine/store": "npm:7.13.3" react-transition-group: "npm:4.4.5" peerDependencies: - "@mantine/core": 7.12.1 - "@mantine/hooks": 7.12.1 + "@mantine/core": 7.13.3 + "@mantine/hooks": 7.13.3 react: ^18.2.0 react-dom: ^18.2.0 - checksum: 10/492e1a90a4bade6add29d817038d7a7195f30ca6c58318d6ffcfa46b29672b7c262257cbc9ff1773fed0a9bf41d73ba8eadee0a70b381784d1f08f6f3e2e126b + checksum: 10/b0db5bfdd9999f83e5d003908d6dd1b3bcb92a7b949cb4a3cb5e6fa204391b137bff15e8ab04a6b7d99041d06bce38510138a355256231f2a964691aff352a97 languageName: node linkType: hard -"@mantine/store@npm:7.12.1": - version: 7.12.1 - resolution: "@mantine/store@npm:7.12.1" +"@mantine/store@npm:7.13.3": + version: 7.13.3 + resolution: "@mantine/store@npm:7.13.3" peerDependencies: react: ^18.2.0 - checksum: 10/0aec736d2a9cf37b45534ab353c7eb2c6ab603aade9778ebd81ea63ce0b751c20fdf5eb2a206293a17180daae3afa580bcdf7cc6a029f58c225bf776e69bbc88 + checksum: 10/72b3f7b3c4ddd15acce5b694b1d34a09260a3f6c0cdf059bcf007f9ecfc71fb0a394de0e204015ee740ba403a68dff6c73150f9286e637763883a605bfd8d694 languageName: node linkType: hard @@ -4111,53 +4018,20 @@ __metadata: languageName: node linkType: hard -"@paddle/paddle-js@npm:1.2.0": - version: 1.2.0 - resolution: "@paddle/paddle-js@npm:1.2.0" - checksum: 10/87bf72de59f6ef728dcba9581c893608c09b8d897414f8fff4544461db3a54231709e723a79c3090768072169b9981f92fbb51b6ea836142328741593c077192 +"@paddle/paddle-js@npm:1.2.3": + version: 1.2.3 + resolution: "@paddle/paddle-js@npm:1.2.3" + checksum: 10/6d4cc3b90305b26b30acdbf2b199a949f2e89dffbd7eba1dbebd5a1c58be533dc476984a49778a9284c3a026abba21b3ab1c1136d400974635641de96450d5d1 languageName: node linkType: hard -"@paddle/paddle-node-sdk@npm:1.4.1": - version: 1.4.1 - resolution: "@paddle/paddle-node-sdk@npm:1.4.1" +"@paddle/paddle-node-sdk@npm:1.9.1": + version: 1.9.1 + resolution: "@paddle/paddle-node-sdk@npm:1.9.1" dependencies: lodash: "npm:^4.17.21" node-fetch: "npm:^2.7.0" - checksum: 10/7b2b4f8a11b3740f87311fba3fbf12498044cfa0631adade896bb11603901d3b1e84b84251a9a1107e21e3a0ba15e352d3791bc5aa967212798e6df1387cca0d - languageName: node - linkType: hard - -"@peculiar/asn1-schema@npm:^2.3.6": - version: 2.3.6 - resolution: "@peculiar/asn1-schema@npm:2.3.6" - dependencies: - asn1js: "npm:^3.0.5" - pvtsutils: "npm:^1.3.2" - tslib: "npm:^2.4.0" - checksum: 10/09e8292b19cca0952629fb26b897de02fd16d1ef897fa7257de350220223b1e544a398f3487e6e2022495ef7c5d186320b8e65c3f640886409c946bbdc277c96 - languageName: node - linkType: hard - -"@peculiar/json-schema@npm:^1.1.12": - version: 1.1.12 - resolution: "@peculiar/json-schema@npm:1.1.12" - dependencies: - tslib: "npm:^2.0.0" - checksum: 10/dfec178afe63a02b6d45da8a18e51ef417e9f5412a8c2809c9a07b29b9376fadee1b4f2ea2d92d4e5a7b8eba76d9e99afbef6d7e9a27bd85257f69c4da228cbc - languageName: node - linkType: hard - -"@peculiar/webcrypto@npm:^1.4.0": - version: 1.4.3 - resolution: "@peculiar/webcrypto@npm:1.4.3" - dependencies: - "@peculiar/asn1-schema": "npm:^2.3.6" - "@peculiar/json-schema": "npm:^1.1.12" - pvtsutils: "npm:^1.3.2" - tslib: "npm:^2.5.0" - webcrypto-core: "npm:^1.7.7" - checksum: 10/548f5e32badcfdb02c903ca240daccac5d87ba841e436bd6d30e5455ced22917146130dab21afb718568ea935d6b04dc66fb33a4b6ab652dd868abff81e74a81 + checksum: 10/6a57f801cc27f7b81a01c5621ac3a1e8533b9ab62ab184ed466d90772fe110f14458f6ea6692a483b2f87dc9e2390550098f12130e81f5e8f12d1b3209a77285 languageName: node linkType: hard @@ -4393,6 +4267,19 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-context@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-context@npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/f6469583bf11cc7bff3ea5c95c56b0774a959512adead00dc64b0527cca01b90b476ca39a64edfd7e18e428e17940aa0339116b1ce5b6e8eab513cfd1065d391 + languageName: node + linkType: hard + "@radix-ui/react-direction@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-direction@npm:1.0.1" @@ -4468,6 +4355,29 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-dismissable-layer@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-dismissable-layer@npm:1.1.1" + dependencies: + "@radix-ui/primitive": "npm:1.1.0" + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-use-callback-ref": "npm:1.1.0" + "@radix-ui/react-use-escape-keydown": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/4f2346846f15f3482b8b6cd850448838d01520366deef840d8e80f5a3443aa7f21f86bd5b9a26f2709dcf94f1ec3f2bdfe80d5c37cba504c41e487c7ff8af3de + languageName: node + linkType: hard + "@radix-ui/react-focus-guards@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-focus-guards@npm:1.0.1" @@ -4719,6 +4629,26 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-portal@npm:1.1.2": + version: 1.1.2 + resolution: "@radix-ui/react-portal@npm:1.1.2" + dependencies: + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-use-layout-effect": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/2f737dc0445f02f512f814ba140227e1a049b3d215d79e22ead412c9befe830292c48a559a8ad1514a474ae8f0c4c43954dfbe294b93a0279d8747d08f7b7924 + languageName: node + linkType: hard + "@radix-ui/react-presence@npm:1.1.0": version: 1.1.0 resolution: "@radix-ui/react-presence@npm:1.1.0" @@ -4739,6 +4669,26 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-presence@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-presence@npm:1.1.1" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-use-layout-effect": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/1ae074efae47ab52a63239a5936fddb334b2f66ed91e74bfe8b1ae591e5db01fa7e9ddb1412002cc043066d40478ba05187a27eb2684dcd68dea545993f9ee20 + languageName: node + linkType: hard + "@radix-ui/react-primitive@npm:1.0.3": version: 1.0.3 resolution: "@radix-ui/react-primitive@npm:1.0.3" @@ -4952,18 +4902,18 @@ __metadata: languageName: node linkType: hard -"@radix-ui/react-tooltip@npm:1.1.2": - version: 1.1.2 - resolution: "@radix-ui/react-tooltip@npm:1.1.2" +"@radix-ui/react-tooltip@npm:1.1.3": + version: 1.1.3 + resolution: "@radix-ui/react-tooltip@npm:1.1.3" dependencies: "@radix-ui/primitive": "npm:1.1.0" "@radix-ui/react-compose-refs": "npm:1.1.0" - "@radix-ui/react-context": "npm:1.1.0" - "@radix-ui/react-dismissable-layer": "npm:1.1.0" + "@radix-ui/react-context": "npm:1.1.1" + "@radix-ui/react-dismissable-layer": "npm:1.1.1" "@radix-ui/react-id": "npm:1.1.0" "@radix-ui/react-popper": "npm:1.2.0" - "@radix-ui/react-portal": "npm:1.1.1" - "@radix-ui/react-presence": "npm:1.1.0" + "@radix-ui/react-portal": "npm:1.1.2" + "@radix-ui/react-presence": "npm:1.1.1" "@radix-ui/react-primitive": "npm:2.0.0" "@radix-ui/react-slot": "npm:1.1.0" "@radix-ui/react-use-controllable-state": "npm:1.1.0" @@ -4978,7 +4928,7 @@ __metadata: optional: true "@types/react-dom": optional: true - checksum: 10/d8386260d2710720b3d87fdacc04597935e5f6eb1d0375516dd362c2f00bf07ea1fceb4c4bda76ec332ebbcf6a4b88f04050add1a9a4db0f13a5ac12b1190355 + checksum: 10/6a0eeabee30173b3d885c12c666614d673352037c0018a57e4cf220d4da73b6ebefa8610fe26a99d83fc00672a2b7417d8dc194096dd106865de1326d8cd9166 languageName: node linkType: hard @@ -5232,6 +5182,15 @@ __metadata: languageName: node linkType: hard +"@react-email/body@npm:0.0.10": + version: 0.0.10 + resolution: "@react-email/body@npm:0.0.10" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/68c1cd8e5f53476849981c625cabc172eca02b53dc97a883e5d7b21264d4b53e005e085abbec7b1635ad575b570becfa6e6a96adeb9e75a086c23243bc0d7080 + languageName: node + linkType: hard + "@react-email/body@npm:0.0.9": version: 0.0.9 resolution: "@react-email/body@npm:0.0.9" @@ -5250,6 +5209,15 @@ __metadata: languageName: node linkType: hard +"@react-email/button@npm:0.0.17": + version: 0.0.17 + resolution: "@react-email/button@npm:0.0.17" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/9fab2e3d4ba39990816c49d3265ff89598cc804f6e3d1e85afaf5264657d1ead6acf88e0ad0991ece8d685c1722179d1d4a6274168548c0a765cb7b2519896af + languageName: node + linkType: hard + "@react-email/code-block@npm:0.0.6": version: 0.0.6 resolution: "@react-email/code-block@npm:0.0.6" @@ -5261,6 +5229,17 @@ __metadata: languageName: node linkType: hard +"@react-email/code-block@npm:0.0.9": + version: 0.0.9 + resolution: "@react-email/code-block@npm:0.0.9" + dependencies: + prismjs: "npm:1.29.0" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/77a8b89119b6f88d423d931b2d3ac3faefbbc25290c53219db45021f12691d4deda675929cf5ba4acc7eb8740e11408b048ce3f5c86fe715f551e9a70c1e4998 + languageName: node + linkType: hard + "@react-email/code-inline@npm:0.0.3": version: 0.0.3 resolution: "@react-email/code-inline@npm:0.0.3" @@ -5270,6 +5249,15 @@ __metadata: languageName: node linkType: hard +"@react-email/code-inline@npm:0.0.4": + version: 0.0.4 + resolution: "@react-email/code-inline@npm:0.0.4" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/6d379ce85f76e27074b3494ed21ba32047583bf4f9a68c7256c95c7b1b4a67fd69ffc7f94a923a7149e5378b17164bb1cc2ccec82fe0a309f2c62a0a2fd90cb7 + languageName: node + linkType: hard + "@react-email/column@npm:0.0.11": version: 0.0.11 resolution: "@react-email/column@npm:0.0.11" @@ -5279,6 +5267,15 @@ __metadata: languageName: node linkType: hard +"@react-email/column@npm:0.0.12": + version: 0.0.12 + resolution: "@react-email/column@npm:0.0.12" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/d6b70e3c7a3ebc405945572a3d3dae8ec9e5c4ab1c70ab58c00c8467a1dcce29c44a513f550f5c70d0d960111d7000c487d75751e6f1f27b6c9c2c08245b787c + languageName: node + linkType: hard + "@react-email/components@npm:0.0.22": version: 0.0.22 resolution: "@react-email/components@npm:0.0.22" @@ -5309,6 +5306,36 @@ __metadata: languageName: node linkType: hard +"@react-email/components@npm:0.0.25": + version: 0.0.25 + resolution: "@react-email/components@npm:0.0.25" + dependencies: + "@react-email/body": "npm:0.0.10" + "@react-email/button": "npm:0.0.17" + "@react-email/code-block": "npm:0.0.9" + "@react-email/code-inline": "npm:0.0.4" + "@react-email/column": "npm:0.0.12" + "@react-email/container": "npm:0.0.14" + "@react-email/font": "npm:0.0.8" + "@react-email/head": "npm:0.0.11" + "@react-email/heading": "npm:0.0.14" + "@react-email/hr": "npm:0.0.10" + "@react-email/html": "npm:0.0.10" + "@react-email/img": "npm:0.0.10" + "@react-email/link": "npm:0.0.10" + "@react-email/markdown": "npm:0.0.12" + "@react-email/preview": "npm:0.0.11" + "@react-email/render": "npm:1.0.1" + "@react-email/row": "npm:0.0.10" + "@react-email/section": "npm:0.0.14" + "@react-email/tailwind": "npm:0.1.0" + "@react-email/text": "npm:0.0.10" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/e4fbefc1883043d375b53ffab7d8ebc93f605ac227203256535701592c819be69c4fbfc637c85ebfacc897b0ae0f2f0183049acdb4674233dd8049e7d9eba09c + languageName: node + linkType: hard + "@react-email/container@npm:0.0.13": version: 0.0.13 resolution: "@react-email/container@npm:0.0.13" @@ -5318,6 +5345,15 @@ __metadata: languageName: node linkType: hard +"@react-email/container@npm:0.0.14": + version: 0.0.14 + resolution: "@react-email/container@npm:0.0.14" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/2dc58f162e41af49a1304216fc3e97a60ef4868670dd2aa0d860a8db2ac38622522ec4364bf9ac7541acb321baaaf76b29f8f7bfa3543c3360a584521eb48c6c + languageName: node + linkType: hard + "@react-email/font@npm:0.0.7": version: 0.0.7 resolution: "@react-email/font@npm:0.0.7" @@ -5327,6 +5363,15 @@ __metadata: languageName: node linkType: hard +"@react-email/font@npm:0.0.8": + version: 0.0.8 + resolution: "@react-email/font@npm:0.0.8" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/ce93b03c29d721f6a93f63fdfa29590c96785b8e9689bdb01e70ee482ff43a4834096092b7f888ee750fb57fe8fed4f9c990dd5c63d22af12ee592ca8f1fb2db + languageName: node + linkType: hard + "@react-email/head@npm:0.0.10": version: 0.0.10 resolution: "@react-email/head@npm:0.0.10" @@ -5336,8 +5381,17 @@ __metadata: languageName: node linkType: hard -"@react-email/heading@npm:0.0.13": - version: 0.0.13 +"@react-email/head@npm:0.0.11": + version: 0.0.11 + resolution: "@react-email/head@npm:0.0.11" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/2531af0b6dd0d3c258c6f287015ba008ac24bc219f2b25b0c8e8793d50ce67014405ef238eda41b3589fc10329e7337d2dcda881f3e097919cc6cbb13ea98378 + languageName: node + linkType: hard + +"@react-email/heading@npm:0.0.13": + version: 0.0.13 resolution: "@react-email/heading@npm:0.0.13" dependencies: "@radix-ui/react-slot": "npm:1.1.0" @@ -5347,6 +5401,24 @@ __metadata: languageName: node linkType: hard +"@react-email/heading@npm:0.0.14": + version: 0.0.14 + resolution: "@react-email/heading@npm:0.0.14" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/57214a826655f288ba98ab580ad51981f2d708040238290301c7dc9f353f56d8f84b0c4cdb6fd4d50908c83275e9abdf52eeb61bb47772a32791209b0844c2e7 + languageName: node + linkType: hard + +"@react-email/hr@npm:0.0.10": + version: 0.0.10 + resolution: "@react-email/hr@npm:0.0.10" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/a460e56a3e9aea23c04c087f6e7c35481ad778077f468c3572f44e5631b4efb20404655e96b20978ece8f170315382d82a33ed01e38758345159b16fee39f12b + languageName: node + linkType: hard + "@react-email/hr@npm:0.0.9": version: 0.0.9 resolution: "@react-email/hr@npm:0.0.9" @@ -5356,6 +5428,15 @@ __metadata: languageName: node linkType: hard +"@react-email/html@npm:0.0.10": + version: 0.0.10 + resolution: "@react-email/html@npm:0.0.10" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/e292bff395f0887625d8b9f708767666917cb3a4d4b2b5dcebd947437c53e25fd993e77c6ea5d61f8f751b3688f60972c7446060b610b0ace2d9230670df029e + languageName: node + linkType: hard + "@react-email/html@npm:0.0.9": version: 0.0.9 resolution: "@react-email/html@npm:0.0.9" @@ -5365,6 +5446,15 @@ __metadata: languageName: node linkType: hard +"@react-email/img@npm:0.0.10": + version: 0.0.10 + resolution: "@react-email/img@npm:0.0.10" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/be07ad4107903b34b52c8e699c24e5991c7890be50cea294a2a5d89a92209427fdf03c0ab6407254eb872269a816370d0e0c214a02a7a4916ea394eefb8a5bcb + languageName: node + linkType: hard + "@react-email/img@npm:0.0.9": version: 0.0.9 resolution: "@react-email/img@npm:0.0.9" @@ -5374,6 +5464,15 @@ __metadata: languageName: node linkType: hard +"@react-email/link@npm:0.0.10": + version: 0.0.10 + resolution: "@react-email/link@npm:0.0.10" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/153a0013622c8912418267f32c28a6194ea4ecdd12251057a5e221a45faccb11fdfcfef54949f84841fbcbe1e79e3ad7f45d8695172b5e0d250a7bd148c35e06 + languageName: node + linkType: hard + "@react-email/link@npm:0.0.9": version: 0.0.9 resolution: "@react-email/link@npm:0.0.9" @@ -5394,6 +5493,17 @@ __metadata: languageName: node linkType: hard +"@react-email/markdown@npm:0.0.12": + version: 0.0.12 + resolution: "@react-email/markdown@npm:0.0.12" + dependencies: + md-to-react-email: "npm:5.0.2" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/808241dd363af5aca30c8df28c3aa1d8e20056d1d264eb0726b5a1339c87b7e990cd19bb0c9c7935e291cc456f0df1c9b80f9a264507139d212392ff64fa1298 + languageName: node + linkType: hard + "@react-email/preview@npm:0.0.10": version: 0.0.10 resolution: "@react-email/preview@npm:0.0.10" @@ -5403,6 +5513,15 @@ __metadata: languageName: node linkType: hard +"@react-email/preview@npm:0.0.11": + version: 0.0.11 + resolution: "@react-email/preview@npm:0.0.11" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/661b1a5d2f68a224bcd58f2cab46141c14e964f1fced470a47cfa795cabe383568ac6c6ad3fc1b3f5191098ea236bd0559c541309e67c6b2e86af00c7a9ac565 + languageName: node + linkType: hard + "@react-email/render@npm:0.0.17": version: 0.0.17 resolution: "@react-email/render@npm:0.0.17" @@ -5417,6 +5536,29 @@ __metadata: languageName: node linkType: hard +"@react-email/render@npm:1.0.1": + version: 1.0.1 + resolution: "@react-email/render@npm:1.0.1" + dependencies: + html-to-text: "npm:9.0.5" + js-beautify: "npm:^1.14.11" + react-promise-suspense: "npm:0.3.4" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/0ddc28a8a523802c34f4fe0e69de93c0d495ba05357a7061bee1ea34e29a4c17a4bba82569568b920006d17a2e67689b9b1cb41b106e684b826ed7017d49b4d2 + languageName: node + linkType: hard + +"@react-email/row@npm:0.0.10": + version: 0.0.10 + resolution: "@react-email/row@npm:0.0.10" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/23288ca36b992e30ff1bc34320da3bbf40782e84b4201f5e4c3dba6176f29c3225b7f0062122a5577bb52eacfadc5ca9fd18ee465b1ab67400c1277300dff111 + languageName: node + linkType: hard + "@react-email/row@npm:0.0.9": version: 0.0.9 resolution: "@react-email/row@npm:0.0.9" @@ -5435,6 +5577,15 @@ __metadata: languageName: node linkType: hard +"@react-email/section@npm:0.0.14": + version: 0.0.14 + resolution: "@react-email/section@npm:0.0.14" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/c18a1d47a4dadb49fd48ac004127f40247a0d28b523aea1e610c3d73439c2c00bd582b3c56aa6fec292acba97a431beea29292766950e58cbf0d13cb32d4bb2a + languageName: node + linkType: hard + "@react-email/tailwind@npm:0.0.19": version: 0.0.19 resolution: "@react-email/tailwind@npm:0.0.19" @@ -5444,6 +5595,24 @@ __metadata: languageName: node linkType: hard +"@react-email/tailwind@npm:0.1.0": + version: 0.1.0 + resolution: "@react-email/tailwind@npm:0.1.0" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/3e002b23e0c72d6e27b8be9c640e7b7392aec651b6bc50a8a92064d398e66615b1a1647f4641302f7e1949a7d7878c88c8f3b4b98f295b0882875b4a097f2122 + languageName: node + linkType: hard + +"@react-email/text@npm:0.0.10": + version: 0.0.10 + resolution: "@react-email/text@npm:0.0.10" + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + checksum: 10/b4deb47df62b4c8ecb230debc478331cac650c684b819a11ef930fd4b9700c5a9d408bf4cca27d07638891bafd22c7c35730d434221f0d2d89dde1b01a5d2ad6 + languageName: node + linkType: hard + "@react-email/text@npm:0.0.9": version: 0.0.9 resolution: "@react-email/text@npm:0.0.9" @@ -5509,87 +5678,9 @@ __metadata: languageName: node linkType: hard -"@remix-run/dev@npm:2.10.3": - version: 2.10.3 - resolution: "@remix-run/dev@npm:2.10.3" - dependencies: - "@babel/core": "npm:^7.21.8" - "@babel/generator": "npm:^7.21.5" - "@babel/parser": "npm:^7.21.8" - "@babel/plugin-syntax-decorators": "npm:^7.22.10" - "@babel/plugin-syntax-jsx": "npm:^7.21.4" - "@babel/preset-typescript": "npm:^7.21.5" - "@babel/traverse": "npm:^7.23.2" - "@babel/types": "npm:^7.22.5" - "@mdx-js/mdx": "npm:^2.3.0" - "@npmcli/package-json": "npm:^4.0.1" - "@remix-run/node": "npm:2.10.3" - "@remix-run/router": "npm:1.18.0" - "@remix-run/server-runtime": "npm:2.10.3" - "@types/mdx": "npm:^2.0.5" - "@vanilla-extract/integration": "npm:^6.2.0" - arg: "npm:^5.0.1" - cacache: "npm:^17.1.3" - chalk: "npm:^4.1.2" - chokidar: "npm:^3.5.1" - cross-spawn: "npm:^7.0.3" - dotenv: "npm:^16.0.0" - es-module-lexer: "npm:^1.3.1" - esbuild: "npm:0.17.6" - esbuild-plugins-node-modules-polyfill: "npm:^1.6.0" - execa: "npm:5.1.1" - exit-hook: "npm:2.2.1" - express: "npm:^4.19.2" - fs-extra: "npm:^10.0.0" - get-port: "npm:^5.1.1" - gunzip-maybe: "npm:^1.4.2" - jsesc: "npm:3.0.2" - json5: "npm:^2.2.2" - lodash: "npm:^4.17.21" - lodash.debounce: "npm:^4.0.8" - minimatch: "npm:^9.0.0" - ora: "npm:^5.4.1" - picocolors: "npm:^1.0.0" - picomatch: "npm:^2.3.1" - pidtree: "npm:^0.6.0" - postcss: "npm:^8.4.19" - postcss-discard-duplicates: "npm:^5.1.0" - postcss-load-config: "npm:^4.0.1" - postcss-modules: "npm:^6.0.0" - prettier: "npm:^2.7.1" - pretty-ms: "npm:^7.0.1" - react-refresh: "npm:^0.14.0" - remark-frontmatter: "npm:4.0.1" - remark-mdx-frontmatter: "npm:^1.0.1" - semver: "npm:^7.3.7" - set-cookie-parser: "npm:^2.6.0" - tar-fs: "npm:^2.1.1" - tsconfig-paths: "npm:^4.0.0" - ws: "npm:^7.4.5" - peerDependencies: - "@remix-run/react": ^2.10.3 - "@remix-run/serve": ^2.10.3 - typescript: ^5.1.0 - vite: ^5.1.0 - wrangler: ^3.28.2 - peerDependenciesMeta: - "@remix-run/serve": - optional: true - typescript: - optional: true - vite: - optional: true - wrangler: - optional: true - bin: - remix: dist/cli.js - checksum: 10/44e5429ff2efd35a882d4050b4485b4b28b9bd2a74b394b7d2442ba2df164e2b2539af3db4501e628bba2888c08d39324bed600f5117e5d3184650faaf9a53a1 - languageName: node - linkType: hard - -"@remix-run/dev@npm:2.11.2": - version: 2.11.2 - resolution: "@remix-run/dev@npm:2.11.2" +"@remix-run/dev@npm:2.13.1": + version: 2.13.1 + resolution: "@remix-run/dev@npm:2.13.1" dependencies: "@babel/core": "npm:^7.21.8" "@babel/generator": "npm:^7.21.5" @@ -5601,9 +5692,9 @@ __metadata: "@babel/types": "npm:^7.22.5" "@mdx-js/mdx": "npm:^2.3.0" "@npmcli/package-json": "npm:^4.0.1" - "@remix-run/node": "npm:2.11.2" - "@remix-run/router": "npm:1.19.1" - "@remix-run/server-runtime": "npm:2.11.2" + "@remix-run/node": "npm:2.13.1" + "@remix-run/router": "npm:1.20.0" + "@remix-run/server-runtime": "npm:2.13.1" "@types/mdx": "npm:^2.0.5" "@vanilla-extract/integration": "npm:^6.2.0" arg: "npm:^5.0.1" @@ -5617,7 +5708,7 @@ __metadata: esbuild-plugins-node-modules-polyfill: "npm:^1.6.0" execa: "npm:5.1.1" exit-hook: "npm:2.2.1" - express: "npm:^4.19.2" + express: "npm:^4.20.0" fs-extra: "npm:^10.0.0" get-port: "npm:^5.1.1" gunzip-maybe: "npm:^1.4.2" @@ -5643,10 +5734,10 @@ __metadata: set-cookie-parser: "npm:^2.6.0" tar-fs: "npm:^2.1.1" tsconfig-paths: "npm:^4.0.0" - ws: "npm:^7.4.5" + ws: "npm:^7.5.10" peerDependencies: - "@remix-run/react": ^2.11.2 - "@remix-run/serve": ^2.11.2 + "@remix-run/react": ^2.13.1 + "@remix-run/serve": ^2.13.1 typescript: ^5.1.0 vite: ^5.1.0 wrangler: ^3.28.2 @@ -5661,65 +5752,30 @@ __metadata: optional: true bin: remix: dist/cli.js - checksum: 10/e89b2fc46c730b17c8140eeb5b8251dd1b86f63d6518e764b236959e2c43d9b7e1b752e6a87c26db089f2820812f7b0623048519c06b872d36ec3b53b797881b - languageName: node - linkType: hard - -"@remix-run/express@npm:2.10.3": - version: 2.10.3 - resolution: "@remix-run/express@npm:2.10.3" - dependencies: - "@remix-run/node": "npm:2.10.3" - peerDependencies: - express: ^4.19.2 - typescript: ^5.1.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10/b635fffa1beee32cad4603427766962728106a9daca081caf8538f1831c670a83bbfdfe91b314655c762e88d6ab6987f8d9e544dbe2189922f41b235aa4828c7 - languageName: node - linkType: hard - -"@remix-run/express@npm:2.11.2": - version: 2.11.2 - resolution: "@remix-run/express@npm:2.11.2" - dependencies: - "@remix-run/node": "npm:2.11.2" - peerDependencies: - express: ^4.19.2 - typescript: ^5.1.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10/97e49bffa3c83858fd6077c0b64a61659279f806346d45a389f2bdeed074b6b57fef0735c165296d8c76bab940259d1b83a35c7bec9fbf19e5fe3b02cdf66239 + checksum: 10/73f3420fa753ca5baacec70f14f0dad4465415e918a5d3d7925d0a01bf8fcb87212add61ec7528eea6fc9eb4e62d7e992d7b4d5dfc4887fae8ef1850ead5eb15 languageName: node linkType: hard -"@remix-run/node@npm:2.10.3": - version: 2.10.3 - resolution: "@remix-run/node@npm:2.10.3" +"@remix-run/express@npm:2.13.1": + version: 2.13.1 + resolution: "@remix-run/express@npm:2.13.1" dependencies: - "@remix-run/server-runtime": "npm:2.10.3" - "@remix-run/web-fetch": "npm:^4.4.2" - "@web3-storage/multipart-parser": "npm:^1.0.0" - cookie-signature: "npm:^1.1.0" - source-map-support: "npm:^0.5.21" - stream-slice: "npm:^0.1.2" - undici: "npm:^6.11.1" + "@remix-run/node": "npm:2.13.1" peerDependencies: + express: ^4.20.0 typescript: ^5.1.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/70fa59c6ee56f64f89c93a844a18b8781386262d2f49edcd34c3e14f2ec6aeae90070fa8f35213133267e73ec91719efc35be38310b97ae0a0e5c738ac4718f7 + checksum: 10/3f7f1e193ac52183ef6183eabbac76f9a6e5659f1ee70bb8cf284ffe1c1dd6409bd9deee71f6bbda136b407a5a34ec08de0fe0a286c368fa6aba3049de559b06 languageName: node linkType: hard -"@remix-run/node@npm:2.11.2": - version: 2.11.2 - resolution: "@remix-run/node@npm:2.11.2" +"@remix-run/node@npm:2.13.1": + version: 2.13.1 + resolution: "@remix-run/node@npm:2.13.1" dependencies: - "@remix-run/server-runtime": "npm:2.11.2" + "@remix-run/server-runtime": "npm:2.13.1" "@remix-run/web-fetch": "npm:^4.4.2" "@web3-storage/multipart-parser": "npm:^1.0.0" cookie-signature: "npm:^1.1.0" @@ -5731,39 +5787,19 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/ebbb31bc22b6b44f8ff538e2e53f8527c7bbe0486e258dcb4271f5cb2dd13eae30008d415d969bed72713b1d50ed06b0399fc9f32aa7008b2272a04e431b28c5 - languageName: node - linkType: hard - -"@remix-run/react@npm:2.10.3": - version: 2.10.3 - resolution: "@remix-run/react@npm:2.10.3" - dependencies: - "@remix-run/router": "npm:1.18.0" - "@remix-run/server-runtime": "npm:2.10.3" - react-router: "npm:6.25.0" - react-router-dom: "npm:6.25.0" - turbo-stream: "npm:2.2.0" - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 - typescript: ^5.1.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10/0766017c3b9497f8d6ee51ab643a9fe85cc65dd50e6afa8c4601bfa4d72fc4dc5ca42711e46aff9f069ca002bd1a583a86d1278007d70144c16552568f5e7394 + checksum: 10/f1abec9a776cb71f22e358e54db582e16feb0470b93a4b9dae27f0ae85821f4c7d4e9268c1bb881b0deec078498408a93b3c56e27fe3a26f095ec59f229bf5b8 languageName: node linkType: hard -"@remix-run/react@npm:2.11.2": - version: 2.11.2 - resolution: "@remix-run/react@npm:2.11.2" +"@remix-run/react@npm:2.13.1": + version: 2.13.1 + resolution: "@remix-run/react@npm:2.13.1" dependencies: - "@remix-run/router": "npm:1.19.1" - "@remix-run/server-runtime": "npm:2.11.2" - react-router: "npm:6.26.1" - react-router-dom: "npm:6.26.1" - turbo-stream: "npm:2.3.0" + "@remix-run/router": "npm:1.20.0" + "@remix-run/server-runtime": "npm:2.13.1" + react-router: "npm:6.27.0" + react-router-dom: "npm:6.27.0" + turbo-stream: "npm:2.4.0" peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 @@ -5771,21 +5807,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/d8abc2daa1578798b4cf193ace042013310097720f3017b04d4a9693fcd2d87c85db0c438673b4a238efabbf6f0ad87e83341da340783949340c2f9bfd4b6c8c - languageName: node - linkType: hard - -"@remix-run/router@npm:1.18.0": - version: 1.18.0 - resolution: "@remix-run/router@npm:1.18.0" - checksum: 10/f878cf246b94368f431a51363f1d33dc35ad11cb910d930476d988825b024a152de87a7f74f0891c3e7182228f892c7f64f94409aae27084c320338dee82caa1 - languageName: node - linkType: hard - -"@remix-run/router@npm:1.19.1": - version: 1.19.1 - resolution: "@remix-run/router@npm:1.19.1" - checksum: 10/2800c2f6567a982fe942aacc4cb5b170e7cc89bd455960e3bea2424161ff7dac32d01886322d88dd19b88d1bea711f39566d17f02b73eeb74999affb471f8f52 + checksum: 10/74d7463940114d5a7f1aa30250680b46ab0a1e55c9b3ec8e1281e6e73309873bf5a8479932fdc9b592383556e052ff2c1b8e6b45f4197e50dd87c77689e49c07 languageName: node linkType: hard @@ -5796,79 +5818,48 @@ __metadata: languageName: node linkType: hard -"@remix-run/serve@npm:2.10.3": - version: 2.10.3 - resolution: "@remix-run/serve@npm:2.10.3" - dependencies: - "@remix-run/express": "npm:2.10.3" - "@remix-run/node": "npm:2.10.3" - chokidar: "npm:^3.5.3" - compression: "npm:^1.7.4" - express: "npm:^4.19.2" - get-port: "npm:5.1.1" - morgan: "npm:^1.10.0" - source-map-support: "npm:^0.5.21" - bin: - remix-serve: dist/cli.js - checksum: 10/05c179518f4c1fe853077d50759e9441434bab824e7b63a010d236bb411eba2f06aa50430938c91d2ab2270828b29023333e3b6083b038c08df44c334d3b51cf +"@remix-run/router@npm:1.20.0": + version: 1.20.0 + resolution: "@remix-run/router@npm:1.20.0" + checksum: 10/e1d2420db94a1855b97f1784898d0ae389cf3b77129b8f419e51d4833b77ca2c92ac09e2cb558015324d64580a138fd6faa31e52fcc3ba90e3cc382a1a324d4a languageName: node linkType: hard -"@remix-run/serve@npm:2.11.2": - version: 2.11.2 - resolution: "@remix-run/serve@npm:2.11.2" +"@remix-run/serve@npm:2.13.1": + version: 2.13.1 + resolution: "@remix-run/serve@npm:2.13.1" dependencies: - "@remix-run/express": "npm:2.11.2" - "@remix-run/node": "npm:2.11.2" + "@remix-run/express": "npm:2.13.1" + "@remix-run/node": "npm:2.13.1" chokidar: "npm:^3.5.3" compression: "npm:^1.7.4" - express: "npm:^4.19.2" + express: "npm:^4.20.0" get-port: "npm:5.1.1" morgan: "npm:^1.10.0" source-map-support: "npm:^0.5.21" bin: remix-serve: dist/cli.js - checksum: 10/c6a1d4682c4981456ecdcd1e47b28a034820c46526c1ee2bd728d9211cbd5c36d8134a02e30f48008e12ac0447c81b3d386ab2b117a488fa110194e6f387de95 + checksum: 10/2b60e456073f35a398273f48c16da9764221e31d6430c69081f85f7d0c615ad96a3a0938f544512ad7f17399ec73d379a2d614c82cf571011dc2115c81f23dd6 languageName: node linkType: hard -"@remix-run/server-runtime@npm:2.10.3": - version: 2.10.3 - resolution: "@remix-run/server-runtime@npm:2.10.3" - dependencies: - "@remix-run/router": "npm:1.18.0" - "@types/cookie": "npm:^0.6.0" - "@web3-storage/multipart-parser": "npm:^1.0.0" - cookie: "npm:^0.6.0" - set-cookie-parser: "npm:^2.4.8" - source-map: "npm:^0.7.3" - turbo-stream: "npm:2.2.0" - peerDependencies: - typescript: ^5.1.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10/7abcc23cb0585c591e2ed2e19fa87c18a0a572ba8cf1103268c4209beda047b574c22f4a76ec55c90af8522af1c7037b1588e33ba0538f3f136f547e399b6aa7 - languageName: node - linkType: hard - -"@remix-run/server-runtime@npm:2.11.2": - version: 2.11.2 - resolution: "@remix-run/server-runtime@npm:2.11.2" +"@remix-run/server-runtime@npm:2.13.1": + version: 2.13.1 + resolution: "@remix-run/server-runtime@npm:2.13.1" dependencies: - "@remix-run/router": "npm:1.19.1" + "@remix-run/router": "npm:1.20.0" "@types/cookie": "npm:^0.6.0" "@web3-storage/multipart-parser": "npm:^1.0.0" cookie: "npm:^0.6.0" set-cookie-parser: "npm:^2.4.8" source-map: "npm:^0.7.3" - turbo-stream: "npm:2.3.0" + turbo-stream: "npm:2.4.0" peerDependencies: typescript: ^5.1.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/50399f76369ff6f5e3eaa5e4ce5fc6fff2187212caacc5d60ff8af475a2c60815017e66a68c40d0e1f0bde42a122d90021ec1e415e6a1759e1ee0f425a4f6826 + checksum: 10/f38fb874e0aae963f4106435d26f57142be060e33ec5d023c45909eb7885fb17dec30d8305ab3d7da057f4a7c67c084a0244f88f0b36d7c5d8afecf2ef389dd1 languageName: node linkType: hard @@ -6005,13 +5996,6 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.19.0": - version: 4.19.0 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.19.0" - conditions: os=android & cpu=arm - languageName: node - linkType: hard - "@rollup/rollup-android-arm-eabi@npm:4.21.0": version: 4.21.0 resolution: "@rollup/rollup-android-arm-eabi@npm:4.21.0" @@ -6019,13 +6003,6 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-android-arm64@npm:4.19.0": - version: 4.19.0 - resolution: "@rollup/rollup-android-arm64@npm:4.19.0" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - "@rollup/rollup-android-arm64@npm:4.21.0": version: 4.21.0 resolution: "@rollup/rollup-android-arm64@npm:4.21.0" @@ -6033,13 +6010,6 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-darwin-arm64@npm:4.19.0": - version: 4.19.0 - resolution: "@rollup/rollup-darwin-arm64@npm:4.19.0" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - "@rollup/rollup-darwin-arm64@npm:4.21.0": version: 4.21.0 resolution: "@rollup/rollup-darwin-arm64@npm:4.21.0" @@ -6047,13 +6017,6 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-darwin-x64@npm:4.19.0": - version: 4.19.0 - resolution: "@rollup/rollup-darwin-x64@npm:4.19.0" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - "@rollup/rollup-darwin-x64@npm:4.21.0": version: 4.21.0 resolution: "@rollup/rollup-darwin-x64@npm:4.21.0" @@ -6061,13 +6024,6 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.19.0": - version: 4.19.0 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.19.0" - conditions: os=linux & cpu=arm & libc=glibc - languageName: node - linkType: hard - "@rollup/rollup-linux-arm-gnueabihf@npm:4.21.0": version: 4.21.0 resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.21.0" @@ -6075,13 +6031,6 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-linux-arm-musleabihf@npm:4.19.0": - version: 4.19.0 - resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.19.0" - conditions: os=linux & cpu=arm & libc=musl - languageName: node - linkType: hard - "@rollup/rollup-linux-arm-musleabihf@npm:4.21.0": version: 4.21.0 resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.21.0" @@ -6089,13 +6038,6 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-linux-arm64-gnu@npm:4.19.0": - version: 4.19.0 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.19.0" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - "@rollup/rollup-linux-arm64-gnu@npm:4.21.0": version: 4.21.0 resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.21.0" @@ -6103,13 +6045,6 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-linux-arm64-musl@npm:4.19.0": - version: 4.19.0 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.19.0" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - "@rollup/rollup-linux-arm64-musl@npm:4.21.0": version: 4.21.0 resolution: "@rollup/rollup-linux-arm64-musl@npm:4.21.0" @@ -6117,13 +6052,6 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-linux-powerpc64le-gnu@npm:4.19.0": - version: 4.19.0 - resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.19.0" - conditions: os=linux & cpu=ppc64 & libc=glibc - languageName: node - linkType: hard - "@rollup/rollup-linux-powerpc64le-gnu@npm:4.21.0": version: 4.21.0 resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.21.0" @@ -6131,13 +6059,6 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-gnu@npm:4.19.0": - version: 4.19.0 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.19.0" - conditions: os=linux & cpu=riscv64 & libc=glibc - languageName: node - linkType: hard - "@rollup/rollup-linux-riscv64-gnu@npm:4.21.0": version: 4.21.0 resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.21.0" @@ -6145,24 +6066,10 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-linux-s390x-gnu@npm:4.19.0": - version: 4.19.0 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.19.0" - conditions: os=linux & cpu=s390x & libc=glibc - languageName: node - linkType: hard - "@rollup/rollup-linux-s390x-gnu@npm:4.21.0": - version: 4.21.0 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.21.0" - conditions: os=linux & cpu=s390x & libc=glibc - languageName: node - linkType: hard - -"@rollup/rollup-linux-x64-gnu@npm:4.19.0": - version: 4.19.0 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.19.0" - conditions: os=linux & cpu=x64 & libc=glibc + version: 4.21.0 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.21.0" + conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard @@ -6173,13 +6080,6 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-linux-x64-musl@npm:4.19.0": - version: 4.19.0 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.19.0" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - "@rollup/rollup-linux-x64-musl@npm:4.21.0": version: 4.21.0 resolution: "@rollup/rollup-linux-x64-musl@npm:4.21.0" @@ -6187,13 +6087,6 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-win32-arm64-msvc@npm:4.19.0": - version: 4.19.0 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.19.0" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - "@rollup/rollup-win32-arm64-msvc@npm:4.21.0": version: 4.21.0 resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.21.0" @@ -6201,13 +6094,6 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-win32-ia32-msvc@npm:4.19.0": - version: 4.19.0 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.19.0" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - "@rollup/rollup-win32-ia32-msvc@npm:4.21.0": version: 4.21.0 resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.21.0" @@ -6215,13 +6101,6 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-win32-x64-msvc@npm:4.19.0": - version: 4.19.0 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.19.0" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - "@rollup/rollup-win32-x64-msvc@npm:4.21.0": version: 4.21.0 resolution: "@rollup/rollup-win32-x64-msvc@npm:4.21.0" @@ -6234,77 +6113,77 @@ __metadata: resolution: "@ryot/frontend@workspace:apps/frontend" dependencies: "@bitprojects/umami-logger-typescript": "npm:1.0.10" - "@conform-to/react": "npm:1.1.5" - "@conform-to/zod": "npm:1.1.5" + "@conform-to/react": "npm:1.2.2" + "@conform-to/zod": "npm:1.2.2" "@formkit/auto-animate": "npm:0.8.2" - "@hello-pangea/dnd": "npm:16.6.0" + "@hello-pangea/dnd": "npm:17.0.0" "@lukemorales/query-key-factory": "npm:1.3.4" - "@mantine/carousel": "npm:7.12.1" - "@mantine/charts": "npm:7.12.1" - "@mantine/core": "npm:7.12.1" - "@mantine/dates": "npm:7.12.1" - "@mantine/form": "npm:7.12.1" - "@mantine/hooks": "npm:7.12.1" - "@mantine/notifications": "npm:7.12.1" + "@mantine/carousel": "npm:7.13.3" + "@mantine/charts": "npm:7.13.3" + "@mantine/core": "npm:7.13.3" + "@mantine/dates": "npm:7.13.3" + "@mantine/form": "npm:7.13.3" + "@mantine/hooks": "npm:7.13.3" + "@mantine/notifications": "npm:7.13.3" "@remix-pwa/dev": "npm:3.1.0" "@remix-pwa/sw": "npm:3.0.10" "@remix-pwa/worker-runtime": "npm:2.1.4" - "@remix-run/dev": "npm:2.11.2" - "@remix-run/node": "npm:2.11.2" - "@remix-run/react": "npm:2.11.2" - "@remix-run/serve": "npm:2.11.2" + "@remix-run/dev": "npm:2.13.1" + "@remix-run/node": "npm:2.13.1" + "@remix-run/react": "npm:2.13.1" + "@remix-run/serve": "npm:2.13.1" "@ryot/generated": "workspace:*" "@ryot/graphql": "workspace:*" "@ryot/ts-utils": "workspace:*" - "@tabler/icons-react": "npm:3.12.0" - "@tanstack/react-query": "npm:5.52.0" - "@tanstack/react-query-devtools": "npm:5.52.0" + "@tabler/icons-react": "npm:3.19.0" + "@tanstack/react-query": "npm:5.59.15" + "@tanstack/react-query-devtools": "npm:5.59.15" "@types/cookie": "npm:0.6.0" "@types/crypto-js": "npm:4.2.2" - "@types/howler": "npm:2.2.11" + "@types/howler": "npm:2.2.12" "@types/js-cookie": "npm:3.0.6" - "@types/react": "npm:18.3.4" - "@types/react-dom": "npm:18.3.0" + "@types/react": "npm:18.3.11" + "@types/react-dom": "npm:18.3.1" "@types/uuid": "npm:10.0.0" buffer: "npm:6.0.3" clsx: "npm:2.1.1" - cookie: "npm:0.6.0" + cookie: "npm:1.0.1" dayjs: "npm:1.11.13" dotenv: "npm:16.4.5" embla-carousel-react: "npm:7.1.0" - filesize: "npm:10.1.4" + filesize: "npm:10.1.6" graphql: "npm:16.9.0" graphql-request: "npm:7.1.0" howler: "npm:2.2.4" humanize-duration-ts: "npm:2.1.1" immer: "npm:10.1.1" isbot: "npm:5.1.17" - jotai: "npm:2.9.3" + jotai: "npm:2.10.1" js-cookie: "npm:3.0.5" jwt-decode: "npm:4.0.0" - mantine-datatable: "npm:7.11.3" - postcss: "npm:8.4.41" + mantine-datatable: "npm:7.12.4" + postcss: "npm:8.4.47" postcss-preset-mantine: "npm:1.17.0" postcss-simple-vars: "npm:7.0.1" react: "npm:18.3.1" react-confirm: "npm:0.3.0-7" react-dom: "npm:18.3.1" - react-virtuoso: "npm:4.10.1" + react-virtuoso: "npm:4.12.0" react-webcam: "npm:7.2.0" - recharts: "npm:2.12.7" - remix-development-tools: "npm:4.4.1" + recharts: "npm:2.13.0" + remix-development-tools: "npm:4.7.3" remix-routes: "npm:1.7.7" - remix-utils: "npm:7.6.0" + remix-utils: "npm:7.7.0" tiny-invariant: "npm:1.3.3" ts-essentials: "npm:10.0.2" - ts-pattern: "npm:5.3.1" - typescript: "npm:5.5.4" + ts-pattern: "npm:5.5.0" + typescript: "npm:5.6.3" typescript-plugin-css-modules: "npm:5.1.0" typescript-remix-routes-plugin: "npm:1.0.1" ufo: "npm:1.5.4" usehooks-ts: "npm:3.1.0" uuid: "npm:10.0.0" - vite: "npm:5.4.2" + vite: "npm:5.4.9" vite-tsconfig-paths: "npm:5.0.1" zod: "npm:3.23.8" zodix: "npm:0.4.4" @@ -6315,8 +6194,8 @@ __metadata: version: 0.0.0-use.local resolution: "@ryot/generated@workspace:libs/generated" dependencies: - "@graphql-codegen/cli": "npm:5.0.2" - "@graphql-codegen/client-preset": "npm:4.3.3" + "@graphql-codegen/cli": "npm:5.0.3" + "@graphql-codegen/client-preset": "npm:4.4.0" "@graphql-typed-document-node/core": "npm:3.2.0" graphql: "npm:16.9.0" languageName: unknown @@ -6335,9 +6214,9 @@ __metadata: version: 0.0.0-use.local resolution: "@ryot/root@workspace:." dependencies: - "@biomejs/biome": "npm:1.8.3" + "@biomejs/biome": "npm:1.9.4" tsconfig-moon: "npm:1.3.0" - typescript: "npm:5.5.4" + typescript: "npm:5.6.3" languageName: unknown linkType: soft @@ -6347,6 +6226,9 @@ __metadata: dependencies: "@react-email/components": "npm:0.0.22" "@ryot/ts-utils": "workspace:*" + "@types/react": "npm:18.3.11" + "@types/react-dom": "npm:18.3.1" + react: "npm:18.3.1" react-dom: "npm:18.3.1" react-email: "npm:2.1.6" languageName: unknown @@ -6356,12 +6238,13 @@ __metadata: version: 0.0.0-use.local resolution: "@ryot/ts-utils@workspace:libs/ts-utils" dependencies: - "@conform-to/zod": "npm:1.1.5" + "@conform-to/zod": "npm:1.2.2" "@ryot/generated": "workspace:*" - "@types/lodash": "npm:4.17.7" + "@types/lodash": "npm:4.17.12" dayjs: "npm:1.11.13" humanize-duration-ts: "npm:2.1.1" lodash: "npm:4.17.21" + tiny-invariant: "npm:1.3.3" languageName: unknown linkType: soft @@ -6369,65 +6252,65 @@ __metadata: version: 0.0.0-use.local resolution: "@ryot/website@workspace:apps/website" dependencies: - "@conform-to/zod": "npm:1.1.5" + "@conform-to/zod": "npm:1.2.2" "@isaacs/ttlcache": "npm:1.4.1" - "@paddle/paddle-js": "npm:1.2.0" - "@paddle/paddle-node-sdk": "npm:1.4.1" + "@paddle/paddle-js": "npm:1.2.3" + "@paddle/paddle-node-sdk": "npm:1.9.1" "@radix-ui/react-label": "npm:2.1.0" "@radix-ui/react-slot": "npm:1.1.0" - "@radix-ui/react-tooltip": "npm:1.1.2" - "@react-email/components": "npm:0.0.22" - "@remix-run/dev": "npm:2.10.3" - "@remix-run/node": "npm:2.10.3" - "@remix-run/react": "npm:2.10.3" - "@remix-run/serve": "npm:2.10.3" + "@radix-ui/react-tooltip": "npm:1.1.3" + "@react-email/components": "npm:0.0.25" + "@remix-run/dev": "npm:2.13.1" + "@remix-run/node": "npm:2.13.1" + "@remix-run/react": "npm:2.13.1" + "@remix-run/serve": "npm:2.13.1" "@ryot/generated": "workspace:*" "@ryot/graphql": "workspace:*" "@ryot/transactional": "workspace:*" "@ryot/ts-utils": "workspace:*" - "@tabler/icons-react": "npm:3.11.0" - "@tailwindcss/typography": "npm:0.5.13" - "@types/crypto-js": "npm:^4" - "@types/lodash": "npm:4.17.7" - "@types/nodemailer": "npm:6" - "@types/react": "npm:18.2.20" - "@types/react-dom": "npm:18.2.7" - "@unkey/api": "npm:0.23.0" - autoprefixer: "npm:10.4.19" + "@tabler/icons-react": "npm:3.19.0" + "@tailwindcss/typography": "npm:0.5.15" + "@types/crypto-js": "npm:^4.2.2" + "@types/lodash": "npm:4.17.12" + "@types/nodemailer": "npm:6.4.16" + "@types/react": "npm:18.3.11" + "@types/react-dom": "npm:18.3.1" + "@unkey/api": "npm:0.26.2" + autoprefixer: "npm:10.4.20" class-variance-authority: "npm:0.7.0" clsx: "npm:2.1.1" crypto-js: "npm:4.2.0" - dayjs: "npm:1.11.12" - drizzle-kit: "npm:0.23.0" - drizzle-orm: "npm:0.32.1" - embla-carousel-autoplay: "npm:8.1.7" - embla-carousel-react: "npm:8.1.7" + dayjs: "npm:1.11.13" + drizzle-kit: "npm:0.26.2" + drizzle-orm: "npm:0.35.3" + embla-carousel-autoplay: "npm:8.3.0" + embla-carousel-react: "npm:8.3.0" graphql: "npm:16.9.0" graphql-request: "npm:7.1.0" humanize-duration-ts: "npm:2.1.1" input-otp: "npm:1.2.4" - isbot: "npm:4.1.0" + isbot: "npm:5.1.17" lodash: "npm:4.17.21" - lucide-react: "npm:0.414.0" + lucide-react: "npm:0.453.0" next-themes: "npm:0.3.0" - nodemailer: "npm:6.9.14" + nodemailer: "npm:6.9.15" openid-client: "npm:5.6.5" - postcss: "npm:8.4.38" + postcss: "npm:8.4.47" postgres: "npm:3.4.4" - react: "npm:18.2.0" - react-dom: "npm:18.2.0" - remix-routes: "npm:1.7.6" - remix-utils: "npm:7.6.0" + react: "npm:18.3.1" + react-dom: "npm:18.3.1" + remix-routes: "npm:1.7.7" + remix-utils: "npm:7.7.0" sonner: "npm:1.5.0" - tailwind-merge: "npm:2.4.0" - tailwindcss: "npm:3.4.4" + tailwind-merge: "npm:2.5.4" + tailwindcss: "npm:3.4.14" tailwindcss-animate: "npm:1.0.7" - ts-pattern: "npm:5.2.0" - typescript: "npm:5.1.6" + ts-pattern: "npm:5.5.0" + typescript: "npm:5.6.3" typescript-remix-routes-plugin: "npm:1.0.1" ufo: "npm:1.5.4" - vite: "npm:5.1.0" - vite-tsconfig-paths: "npm:4.2.1" + vite: "npm:5.4.9" + vite-tsconfig-paths: "npm:5.0.1" zod: "npm:3.23.8" zodix: "npm:0.4.4" languageName: unknown @@ -6583,53 +6466,35 @@ __metadata: linkType: hard "@swc/types@npm:^0.1.5": - version: 0.1.12 - resolution: "@swc/types@npm:0.1.12" + version: 0.1.13 + resolution: "@swc/types@npm:0.1.13" dependencies: "@swc/counter": "npm:^0.1.3" - checksum: 10/92dbbc70cd068ea30fb6fbdc1ae8599d6c058a5d09b2923d6e4e24fab5ad7c86a19dd01f349a8e03e300a9321e06911a24df18303b40e307fbd4109372cef2ef - languageName: node - linkType: hard - -"@tabler/icons-react@npm:3.11.0": - version: 3.11.0 - resolution: "@tabler/icons-react@npm:3.11.0" - dependencies: - "@tabler/icons": "npm:3.11.0" - peerDependencies: - react: ">= 16" - checksum: 10/1011b55f0a1efe327a863c6fdaf6522685d6492b3cddef0e8dfc2fa8326a88c661e13417f3b07a5710b4bbbde6c6830cb3c2309db81a7b20c0b2242f3e89a982 + checksum: 10/d0a50432917048cc69e30c82d1266e052a8e8d05ab202c5d74a5666be3748da4d2f99aaff46d91c0e3d285cf8f55270f8391cd578066fdecc3865733f8d5e14a languageName: node linkType: hard -"@tabler/icons-react@npm:3.12.0": - version: 3.12.0 - resolution: "@tabler/icons-react@npm:3.12.0" +"@tabler/icons-react@npm:3.19.0": + version: 3.19.0 + resolution: "@tabler/icons-react@npm:3.19.0" dependencies: - "@tabler/icons": "npm:3.12.0" + "@tabler/icons": "npm:3.19.0" peerDependencies: react: ">= 16" - checksum: 10/505444ad6040196516da2c876b427c9d70389b486037faafeea5f471e6f793a4471b5338b99eecb755647cfa4e0c327fe1d356cdfe5ce2548947b0372270e46b - languageName: node - linkType: hard - -"@tabler/icons@npm:3.11.0": - version: 3.11.0 - resolution: "@tabler/icons@npm:3.11.0" - checksum: 10/1815b5ba0b1016db4902248f5fbc79dff217b9f41ece950bfa0222cfd92d75740bc9d08ab227d7b9fee93e972df57c0c4d8da8b9769a92e065067aa7d8370a13 + checksum: 10/0b3396519665cdef8e2722b0280f625fb996552ce3f1fde986628929b841f0f7eac036c4f495a16c99f330ae662ab3c527cfc80aa7e0293974d829532021daf1 languageName: node linkType: hard -"@tabler/icons@npm:3.12.0": - version: 3.12.0 - resolution: "@tabler/icons@npm:3.12.0" - checksum: 10/1ab2ebcb3b7a4d5272a58f67091b39881838c04664cb170d729993bc22cf8a65b96d822e76963aa7310f34e7496928dfb3a1fe7d45940bea7fad038a873ac844 +"@tabler/icons@npm:3.19.0": + version: 3.19.0 + resolution: "@tabler/icons@npm:3.19.0" + checksum: 10/f69b346c868bf0092d3650da3febacb5006423aa191f1e1fcb1487b3c5c56dfb4a8876f58286c2f0476acfe4c612c096ca83fdde896562be27405948c1d9556a languageName: node linkType: hard -"@tailwindcss/typography@npm:0.5.13": - version: 0.5.13 - resolution: "@tailwindcss/typography@npm:0.5.13" +"@tailwindcss/typography@npm:0.5.15": + version: 0.5.15 + resolution: "@tailwindcss/typography@npm:0.5.15" dependencies: lodash.castarray: "npm:^4.4.0" lodash.isplainobject: "npm:^4.0.6" @@ -6637,44 +6502,44 @@ __metadata: postcss-selector-parser: "npm:6.0.10" peerDependencies: tailwindcss: "*" - checksum: 10/ffa5fee725d390591f1654fee8275b025248ef0e25a54b1749db23ec82d6117729b933e2326b6d52348ff2844839755f89d5d82fe5900d91b399c9380041b4e9 + checksum: 10/8c677e4de25a5362d757c3c0b9d594b63c789ab287cad846a082ca227e0d3435145793301ced8f32d5215d5c21537195e7d87ca08a6e7a8facf47a11e7f07d22 languageName: node linkType: hard -"@tanstack/query-core@npm:5.52.0": - version: 5.52.0 - resolution: "@tanstack/query-core@npm:5.52.0" - checksum: 10/cd21e87ad7a0bbb262dea21704352eb1bbaafc26776ae1602b4be9a2d0d1f16a89cc4b5951f69083e26f970d75386431240d5a573ed9bce5a37ba2dc862e376a +"@tanstack/query-core@npm:5.59.13": + version: 5.59.13 + resolution: "@tanstack/query-core@npm:5.59.13" + checksum: 10/dc28f8a667095a98e22411a0f067f0c03701c9c92355d1cb74e9b160c49acdf0e5e362cc027ece6a70e4faec721170da2ee38e71f07814c664a2c4cbd494d736 languageName: node linkType: hard -"@tanstack/query-devtools@npm:5.51.16": - version: 5.51.16 - resolution: "@tanstack/query-devtools@npm:5.51.16" - checksum: 10/b0e8c1f86890a515d4ddbab4743387aecd882271f7be2cbc36f69d05ba42b803ae2e9bbfd53a03450ca4827c94f6b5d7d6fa5e013bfabe6ee0aa9a7b34a223d3 +"@tanstack/query-devtools@npm:5.58.0": + version: 5.58.0 + resolution: "@tanstack/query-devtools@npm:5.58.0" + checksum: 10/ca16c47c943ea392dfddc301f7e09ecdb0c8b905fb684b8f26b908a244e2e897679efb0ead5fa8e728711017341fdd91d8c51ebb19f746819e26ade5549f539e languageName: node linkType: hard -"@tanstack/react-query-devtools@npm:5.52.0": - version: 5.52.0 - resolution: "@tanstack/react-query-devtools@npm:5.52.0" +"@tanstack/react-query-devtools@npm:5.59.15": + version: 5.59.15 + resolution: "@tanstack/react-query-devtools@npm:5.59.15" dependencies: - "@tanstack/query-devtools": "npm:5.51.16" + "@tanstack/query-devtools": "npm:5.58.0" peerDependencies: - "@tanstack/react-query": ^5.52.0 + "@tanstack/react-query": ^5.59.15 react: ^18 || ^19 - checksum: 10/67fff9fe45a54e6823800bd15de5d5712b65bda9bb567907765481025775817b03c56925add47dd51fe19de1135b57b290570e5cb00b5a071ca3f7d409c39805 + checksum: 10/89702ee06d09154c8c845dcefc1f39fe6ae507fba7219d41224da35c55d0f4e7c76fc819fc85604d761395ae6638f5864ddd0be41a82b368f55dc5998ce85b90 languageName: node linkType: hard -"@tanstack/react-query@npm:5.52.0": - version: 5.52.0 - resolution: "@tanstack/react-query@npm:5.52.0" +"@tanstack/react-query@npm:5.59.15": + version: 5.59.15 + resolution: "@tanstack/react-query@npm:5.59.15" dependencies: - "@tanstack/query-core": "npm:5.52.0" + "@tanstack/query-core": "npm:5.59.13" peerDependencies: - react: ^18.0.0 - checksum: 10/6976d309d306f0dd70f25e0de820812c47bfc39b654294e1512d4bb5320d0abad1bc3d6de16a25b7ae6766eb9b928c5e396e996d7d6689d33a1c1436de68cf7b + react: ^18 || ^19 + checksum: 10/a55168650140c6e0a3a20adad9e1ef2088a6834a26d7f3455e90177c7dcff2b9ba92fdc330f4d2b1afe246233330b27f71dec003e883ed6aa195490fcf43e803 languageName: node linkType: hard @@ -6717,7 +6582,7 @@ __metadata: languageName: node linkType: hard -"@types/crypto-js@npm:4.2.2, @types/crypto-js@npm:^4": +"@types/crypto-js@npm:4.2.2, @types/crypto-js@npm:^4.2.2": version: 4.2.2 resolution: "@types/crypto-js@npm:4.2.2" checksum: 10/a40fc5a9219fd33f54ba3e094c5e5ab2904d3106681a76f1029bb038976591e9c8959099963bf4474fde21c2d8d00c1f896445206a3a58f85588f9cb1bd96a9a @@ -6745,6 +6610,13 @@ __metadata: languageName: node linkType: hard +"@types/d3-hierarchy@npm:^1.1.8": + version: 1.1.11 + resolution: "@types/d3-hierarchy@npm:1.1.11" + checksum: 10/057948069a5c1a366462bc08d597aaaf8b6f7eb96d785273d20ab56456deb01958c8500de60b491c1bc4cb08c7bf05fdcb6a94ffb91b3548d6b9c1b365840ccc + languageName: node + linkType: hard + "@types/d3-interpolate@npm:^3.0.1": version: 3.0.1 resolution: "@types/d3-interpolate@npm:3.0.1" @@ -6802,26 +6674,6 @@ __metadata: languageName: node linkType: hard -"@types/eslint-scope@npm:^3.7.3": - version: 3.7.7 - resolution: "@types/eslint-scope@npm:3.7.7" - dependencies: - "@types/eslint": "npm:*" - "@types/estree": "npm:*" - checksum: 10/e2889a124aaab0b89af1bab5959847c5bec09809209255de0e63b9f54c629a94781daa04adb66bffcdd742f5e25a17614fb933965093c0eea64aacda4309380e - languageName: node - linkType: hard - -"@types/eslint@npm:*": - version: 9.6.0 - resolution: "@types/eslint@npm:9.6.0" - dependencies: - "@types/estree": "npm:*" - "@types/json-schema": "npm:*" - checksum: 10/39fc797c671ec9c9184802b4974748cf45ee1b11d7aaaaede44426abcafd07ec7c18eb090e8f5b3387b51637ce3fdf54499472d8dd58a928f0d005cbacb573b4 - languageName: node - linkType: hard - "@types/estree-jsx@npm:^1.0.0": version: 1.0.3 resolution: "@types/estree-jsx@npm:1.0.3" @@ -6838,13 +6690,20 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:1.0.5, @types/estree@npm:^1.0.5": +"@types/estree@npm:1.0.5": version: 1.0.5 resolution: "@types/estree@npm:1.0.5" checksum: 10/7de6d928dd4010b0e20c6919e1a6c27b61f8d4567befa89252055fad503d587ecb9a1e3eab1b1901f923964d7019796db810b7fd6430acb26c32866d126fd408 languageName: node linkType: hard +"@types/estree@npm:^1.0.5": + version: 1.0.6 + resolution: "@types/estree@npm:1.0.6" + checksum: 10/9d35d475095199c23e05b431bcdd1f6fec7380612aed068b14b2a08aa70494de8a9026765a5a91b1073f636fb0368f6d8973f518a31391d519e20c59388ed88d + languageName: node + linkType: hard + "@types/hast@npm:^2.0.0": version: 2.3.8 resolution: "@types/hast@npm:2.3.8" @@ -6854,20 +6713,10 @@ __metadata: languageName: node linkType: hard -"@types/hoist-non-react-statics@npm:^3.3.1": - version: 3.3.1 - resolution: "@types/hoist-non-react-statics@npm:3.3.1" - dependencies: - "@types/react": "npm:*" - hoist-non-react-statics: "npm:^3.3.0" - checksum: 10/071e6d75a0ed9aa0e9ca2cc529a8c15bf7ac3e4a37aac279772ea6036fd0bf969b67fb627b65cfce65adeab31fec1e9e95b4dcdefeab075b580c0c7174206f63 - languageName: node - linkType: hard - -"@types/howler@npm:2.2.11": - version: 2.2.11 - resolution: "@types/howler@npm:2.2.11" - checksum: 10/2875810bc1c076cfe7117adaecb88bdd12126b674329488d2b35d4906d15375f606c91cba8ee671fb09bbe2728fd5d396616e9b5144c7a8fca0bdd49e2d410e7 +"@types/howler@npm:2.2.12": + version: 2.2.12 + resolution: "@types/howler@npm:2.2.12" + checksum: 10/94597cf283cdacb4edecd161161ca78b585d3abf342e57f86093ad0eec86d94b7de644fb902a11a6cd1d1bf5225ffd07c336a04a5ba9bdc1cc14c26ff57cb678 languageName: node linkType: hard @@ -6885,7 +6734,7 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.8": +"@types/json-schema@npm:^7.0.8": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 10/1a3c3e06236e4c4aab89499c428d585527ce50c24fe8259e8b3926d3df4cfbbbcf306cfc73ddfb66cbafc973116efd15967020b0f738f63e09e64c7d260519e7 @@ -6899,10 +6748,10 @@ __metadata: languageName: node linkType: hard -"@types/lodash@npm:4.17.7": - version: 4.17.7 - resolution: "@types/lodash@npm:4.17.7" - checksum: 10/b8177f19cf962414a66989837481b13f546afc2e98e8d465bec59e6ac03a59c584eb7053ce511cde3a09c5f3096d22a5ae22cfb56b23f3b0da75b0743b6b1a44 +"@types/lodash@npm:4.17.12": + version: 4.17.12 + resolution: "@types/lodash@npm:4.17.12" + checksum: 10/3d829f97c0ea713135e6eb48e983feffb315f4cf228d03654ca8a328e3fecd03005bf7dd30bf411f4306967c610d96738d441588283a41456815f2ce1fd7044c languageName: node linkType: hard @@ -6952,12 +6801,12 @@ __metadata: languageName: node linkType: hard -"@types/nodemailer@npm:6": - version: 6.4.15 - resolution: "@types/nodemailer@npm:6.4.15" +"@types/nodemailer@npm:6.4.16": + version: 6.4.16 + resolution: "@types/nodemailer@npm:6.4.16" dependencies: "@types/node": "npm:*" - checksum: 10/1b400b694ed1bc51c242a719de44b484911481596c288407fff18b81ee76945d2d0c6e411371dfa4293747ebf4146a1f0df0e188ff7b9d2adaccd1183dfa1c2c + checksum: 10/38e612fef3963c7ae7563f039a8b26d8d4371a7feeedaf38a534f889094f6727fb0d52f565902b01099cfe0b4be7956125ebdae312b9ab3905929df5c815bd95 languageName: node linkType: hard @@ -7007,21 +6856,12 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:18.2.7": - version: 18.2.7 - resolution: "@types/react-dom@npm:18.2.7" - dependencies: - "@types/react": "npm:*" - checksum: 10/9b70ef66cbe2d2898ea37eb79ee3697e0e4ad3d950e769a601f79be94097d43b8ef45b98a0b29528203c7d731c81666f637b2b7032deeced99214b4bc0662614 - languageName: node - linkType: hard - -"@types/react-dom@npm:18.3.0, @types/react-dom@npm:^18.2.0": - version: 18.3.0 - resolution: "@types/react-dom@npm:18.3.0" +"@types/react-dom@npm:18.3.1, @types/react-dom@npm:^18.2.0": + version: 18.3.1 + resolution: "@types/react-dom@npm:18.3.1" dependencies: "@types/react": "npm:*" - checksum: 10/6ff53f5a7b7fba952a68e114d3b542ebdc1e87a794234785ebab0bcd9bde7fb4885f21ebaf93d26dc0a1b5b93287f42cad68b78ae04dddf6b20da7aceff0beaf + checksum: 10/33f9ba79b26641ddf00a8699c30066b7e3573ab254e97475bf08f82fab83a6d3ce8d4ebad86afeb49bb8df3374390a9ba93125cece33badc4b3e8f7eac3c84d8 languageName: node linkType: hard @@ -7083,12 +6923,12 @@ __metadata: languageName: node linkType: hard -"@unkey/api@npm:0.23.0": - version: 0.23.0 - resolution: "@unkey/api@npm:0.23.0" +"@unkey/api@npm:0.26.2": + version: 0.26.2 + resolution: "@unkey/api@npm:0.26.2" dependencies: "@unkey/rbac": "npm:^0.3.1" - checksum: 10/7f3d519c54fbd5097086f61ddd0c0ee5d1771711ea508a45b35ba8cc7df697dd6f62f2baf9e4225663b77dce5411e565a89a3eca3620a7d20dbf357d4ee6d62e + checksum: 10/8fc64b504759ed296e0b79013d2283f3136399991425e91d1bcf5cd5bf42515edd715e094e7f6240462eca0ab0f9f4de6feb5469c2e14be4962dfdd592402f8c languageName: node linkType: hard @@ -7325,13 +7165,6 @@ __metadata: languageName: node linkType: hard -"@whatwg-node/events@npm:^0.0.2": - version: 0.0.2 - resolution: "@whatwg-node/events@npm:0.0.2" - checksum: 10/6d491801d36967d5d62443cca6ef39d41cf882d575839d2e9d1a5f394722cd24ef84fe9e897bb72c01bd198871fda9ff0e8b1ac5aa6f3f814f87d92b7f28fdcc - languageName: node - linkType: hard - "@whatwg-node/events@npm:^0.1.0": version: 0.1.1 resolution: "@whatwg-node/events@npm:0.1.1" @@ -7339,19 +7172,6 @@ __metadata: languageName: node linkType: hard -"@whatwg-node/fetch@npm:^0.8.0": - version: 0.8.5 - resolution: "@whatwg-node/fetch@npm:0.8.5" - dependencies: - "@peculiar/webcrypto": "npm:^1.4.0" - "@whatwg-node/node-fetch": "npm:^0.3.3" - busboy: "npm:^1.6.0" - urlpattern-polyfill: "npm:^7.0.0" - web-streams-polyfill: "npm:^3.2.1" - checksum: 10/1cd426f10a5f33c6d6ff27b8b557d8d083d2b32890d6af56e1d868f4beabf18218d9ac6b43a1d9b4d1dbd7c3b24c9c63b9f8e21bc4d178e46dfd7c15c35b6f71 - languageName: node - linkType: hard - "@whatwg-node/fetch@npm:^0.9.0": version: 0.9.9 resolution: "@whatwg-node/fetch@npm:0.9.9" @@ -7362,16 +7182,13 @@ __metadata: languageName: node linkType: hard -"@whatwg-node/node-fetch@npm:^0.3.3": - version: 0.3.5 - resolution: "@whatwg-node/node-fetch@npm:0.3.5" +"@whatwg-node/fetch@npm:^0.9.20": + version: 0.9.22 + resolution: "@whatwg-node/fetch@npm:0.9.22" dependencies: - "@whatwg-node/events": "npm:^0.0.2" - busboy: "npm:^1.6.0" - fast-querystring: "npm:^1.1.1" - fast-url-parser: "npm:^1.1.3" - tslib: "npm:^2.3.1" - checksum: 10/e75399d20ba3ab634fbd5b92481e93b151760c3fa9734881d3b78c422fa90f2dab1f32b624b709bfde27d924c439dd9cbaad675aa54d3f5f4a44862ce9e0e42d + "@whatwg-node/node-fetch": "npm:^0.5.27" + urlpattern-polyfill: "npm:^10.0.0" + checksum: 10/de6ced46d78dd5b662edd862f15b404ff3ea1aa3a68d92a4b79d920054dfcad6b2532137e7d48448e6301548342992cb25405251be4cf449ed5cdd3ba667a697 languageName: node linkType: hard @@ -7388,6 +7205,18 @@ __metadata: languageName: node linkType: hard +"@whatwg-node/node-fetch@npm:^0.5.27": + version: 0.5.27 + resolution: "@whatwg-node/node-fetch@npm:0.5.27" + dependencies: + "@kamilkisiela/fast-url-parser": "npm:^1.1.4" + busboy: "npm:^1.6.0" + fast-querystring: "npm:^1.1.1" + tslib: "npm:^2.6.3" + checksum: 10/b38abdefaccedb268913aefb66798f386b197dc65a3b9a73ee77438508f06e6c62889c261fff07f001f9e38800bd07b81c2c2667c3ffb5df42890bcf336e7829 + languageName: node + linkType: hard + "@xtuc/ieee754@npm:^1.2.0": version: 1.2.0 resolution: "@xtuc/ieee754@npm:1.2.0" @@ -7479,11 +7308,11 @@ __metadata: linkType: hard "acorn@npm:^8.7.1, acorn@npm:^8.8.2": - version: 8.12.1 - resolution: "acorn@npm:8.12.1" + version: 8.13.0 + resolution: "acorn@npm:8.13.0" bin: acorn: bin/acorn - checksum: 10/d08c2d122bba32d0861e0aa840b2ee25946c286d5dc5990abca991baf8cdbfbe199b05aacb221b979411a2fea36f83e26b5ac4f6b4e0ce49038c62316c1848f0 + checksum: 10/33e3a03114b02b3bc5009463b3d9549b31a90ee38ebccd5e66515830a02acf62a90edcc12abfb6c9fb3837b6c17a3ec9b72b3bf52ac31d8ad8248a4af871e0f5 languageName: node linkType: hard @@ -7699,17 +7528,6 @@ __metadata: languageName: node linkType: hard -"asn1js@npm:^3.0.1, asn1js@npm:^3.0.5": - version: 3.0.5 - resolution: "asn1js@npm:3.0.5" - dependencies: - pvtsutils: "npm:^1.3.2" - pvutils: "npm:^1.1.3" - tslib: "npm:^2.4.0" - checksum: 10/17fb0302432186631550de9606a4622ec366646d072cde9cdf4bcafa47bd2425e157eeb7b1377ee6520f8b46687b4ecaee31cf0ad2fa494361a1938b2ed53194 - languageName: node - linkType: hard - "astral-regex@npm:^2.0.0": version: 2.0.0 resolution: "astral-regex@npm:2.0.0" @@ -7765,21 +7583,21 @@ __metadata: languageName: node linkType: hard -"autoprefixer@npm:10.4.19": - version: 10.4.19 - resolution: "autoprefixer@npm:10.4.19" +"autoprefixer@npm:10.4.20": + version: 10.4.20 + resolution: "autoprefixer@npm:10.4.20" dependencies: - browserslist: "npm:^4.23.0" - caniuse-lite: "npm:^1.0.30001599" + browserslist: "npm:^4.23.3" + caniuse-lite: "npm:^1.0.30001646" fraction.js: "npm:^4.3.7" normalize-range: "npm:^0.1.2" - picocolors: "npm:^1.0.0" + picocolors: "npm:^1.0.1" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.1.0 bin: autoprefixer: bin/autoprefixer - checksum: 10/98378eae37b8bf0f1515e4c91b4c9c1ce69ede311d4dea7e934f5afe147d23712c577f112c4019a4c40461c585d82d474d08044f8eb6cb8a063c3d5b7aca52d2 + checksum: 10/d3c4b562fc4af2393623a0207cc336f5b9f94c4264ae1c316376904c279702ce2b12dc3f27205f491195d1e29bb52ffc269970ceb0f271f035fadee128a273f7 languageName: node linkType: hard @@ -7924,9 +7742,9 @@ __metadata: languageName: node linkType: hard -"body-parser@npm:1.20.2": - version: 1.20.2 - resolution: "body-parser@npm:1.20.2" +"body-parser@npm:1.20.3": + version: 1.20.3 + resolution: "body-parser@npm:1.20.3" dependencies: bytes: "npm:3.1.2" content-type: "npm:~1.0.5" @@ -7936,11 +7754,11 @@ __metadata: http-errors: "npm:2.0.0" iconv-lite: "npm:0.4.24" on-finished: "npm:2.4.1" - qs: "npm:6.11.0" + qs: "npm:6.13.0" raw-body: "npm:2.5.2" type-is: "npm:~1.6.18" unpipe: "npm:1.0.0" - checksum: 10/3cf171b82190cf91495c262b073e425fc0d9e25cc2bf4540d43f7e7bbca27d6a9eae65ca367b6ef3993eea261159d9d2ab37ce444e8979323952e12eb3df319a + checksum: 10/8723e3d7a672eb50854327453bed85ac48d045f4958e81e7d470c56bf111f835b97e5b73ae9f6393d0011cc9e252771f46fd281bbabc57d33d3986edf1e6aeca languageName: node linkType: hard @@ -7981,17 +7799,17 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.21.10, browserslist@npm:^4.21.5, browserslist@npm:^4.23.0, browserslist@npm:^4.23.1": - version: 4.23.2 - resolution: "browserslist@npm:4.23.2" +"browserslist@npm:^4.21.10, browserslist@npm:^4.21.5, browserslist@npm:^4.23.3": + version: 4.24.2 + resolution: "browserslist@npm:4.24.2" dependencies: - caniuse-lite: "npm:^1.0.30001640" - electron-to-chromium: "npm:^1.4.820" - node-releases: "npm:^2.0.14" - update-browserslist-db: "npm:^1.1.0" + caniuse-lite: "npm:^1.0.30001669" + electron-to-chromium: "npm:^1.5.41" + node-releases: "npm:^2.0.18" + update-browserslist-db: "npm:^1.1.1" bin: browserslist: cli.js - checksum: 10/326a98b1c39bcc9a99b197f15790dc28e122b1aead3257c837421899377ac96239123f26868698085b3d9be916d72540602738e1f857e86a387e810af3fda6e5 + checksum: 10/f8a9d78bbabe466c57ffd5c50a9e5582a5df9aa68f43078ca62a9f6d0d6c70ba72eca72d0a574dbf177cf55cdca85a46f7eb474917a47ae5398c66f8b76f7d1c languageName: node linkType: hard @@ -8023,6 +7841,20 @@ __metadata: languageName: node linkType: hard +"browserslist@npm:^4.23.1": + version: 4.23.2 + resolution: "browserslist@npm:4.23.2" + dependencies: + caniuse-lite: "npm:^1.0.30001640" + electron-to-chromium: "npm:^1.4.820" + node-releases: "npm:^2.0.14" + update-browserslist-db: "npm:^1.1.0" + bin: + browserslist: cli.js + checksum: 10/326a98b1c39bcc9a99b197f15790dc28e122b1aead3257c837421899377ac96239123f26868698085b3d9be916d72540602738e1f857e86a387e810af3fda6e5 + languageName: node + linkType: hard + "bser@npm:2.1.1": version: 2.1.1 resolution: "bser@npm:2.1.1" @@ -8144,7 +7976,7 @@ __metadata: languageName: node linkType: hard -"call-bind@npm:^1.0.0, call-bind@npm:^1.0.2": +"call-bind@npm:^1.0.2": version: 1.0.2 resolution: "call-bind@npm:1.0.2" dependencies: @@ -8165,6 +7997,19 @@ __metadata: languageName: node linkType: hard +"call-bind@npm:^1.0.7": + version: 1.0.7 + resolution: "call-bind@npm:1.0.7" + dependencies: + es-define-property: "npm:^1.0.0" + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + get-intrinsic: "npm:^1.2.4" + set-function-length: "npm:^1.2.1" + checksum: 10/cd6fe658e007af80985da5185bff7b55e12ef4c2b6f41829a26ed1eef254b1f1c12e3dfd5b2b068c6ba8b86aba62390842d81752e67dcbaec4f6f76e7113b6b7 + languageName: node + linkType: hard + "callsites@npm:^3.0.0": version: 3.1.0 resolution: "callsites@npm:3.1.0" @@ -8214,10 +8059,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001464, caniuse-lite@npm:^1.0.30001579": - version: 1.0.30001643 - resolution: "caniuse-lite@npm:1.0.30001643" - checksum: 10/dddbda29fa24fbc435873309c71070461cbfc915d9bce3216180524c20c5637b2bee1a14b45972e9ac19e1fdf63fba3f63608b9e7d68de32f5ee1953c8c69e05 +"caniuse-lite@npm:^1.0.30001464, caniuse-lite@npm:^1.0.30001646, caniuse-lite@npm:^1.0.30001669": + version: 1.0.30001669 + resolution: "caniuse-lite@npm:1.0.30001669" + checksum: 10/cd0b481bb997703cb7651e55666b4aa4e7b4ecf9784796e2393179a15e55c71a6abc6ff865c922bbd3bbfa4a4bf0530d8da13989b97ff8c7850c8a5bd4e00491 languageName: node linkType: hard @@ -8228,7 +8073,14 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001599, caniuse-lite@npm:^1.0.30001640": +"caniuse-lite@npm:^1.0.30001579": + version: 1.0.30001643 + resolution: "caniuse-lite@npm:1.0.30001643" + checksum: 10/dddbda29fa24fbc435873309c71070461cbfc915d9bce3216180524c20c5637b2bee1a14b45972e9ac19e1fdf63fba3f63608b9e7d68de32f5ee1953c8c69e05 + languageName: node + linkType: hard + +"caniuse-lite@npm:^1.0.30001640": version: 1.0.30001642 resolution: "caniuse-lite@npm:1.0.30001642" checksum: 10/8d80ea82be453ae0fdfea8766d82740a4945c1b99189650f29bfc458d4e235d7e99027a8f8bc5a4228d8c4457ba896315284b0703f300353ad5f09d8e693de10 @@ -8253,6 +8105,13 @@ __metadata: languageName: node linkType: hard +"chain-function@npm:^1.0.0": + version: 1.0.1 + resolution: "chain-function@npm:1.0.1" + checksum: 10/11b2c4aaea5b37a74717181197312bc95ddfe61a6de7c2b275b34ebb8c2d1e72ce3f20b828dc84982c0b2defc5fc0814bbd3e50f294420f252392ec04de5c806 + languageName: node + linkType: hard + "chalk@npm:4.1.2, chalk@npm:^4.0.0, chalk@npm:^4.0.2, chalk@npm:^4.1.0, chalk@npm:^4.1.1, chalk@npm:^4.1.2": version: 4.1.2 resolution: "chalk@npm:4.1.2" @@ -8505,7 +8364,7 @@ __metadata: languageName: node linkType: hard -"clone@npm:^2.1.2": +"clone@npm:^2.1.1": version: 2.1.2 resolution: "clone@npm:2.1.2" checksum: 10/d9c79efba655f0bf601ab299c57eb54cbaa9860fb011aee9d89ed5ac0d12df1660ab7642fddaabb9a26b7eff0e117d4520512cb70798319ff5d30a111b5310c2 @@ -8761,7 +8620,21 @@ __metadata: languageName: node linkType: hard -"cookie@npm:0.6.0, cookie@npm:^0.6.0": +"cookie@npm:0.7.1": + version: 0.7.1 + resolution: "cookie@npm:0.7.1" + checksum: 10/aec6a6aa0781761bf55d60447d6be08861d381136a0fe94aa084fddd4f0300faa2b064df490c6798adfa1ebaef9e0af9b08a189c823e0811b8b313b3d9a03380 + languageName: node + linkType: hard + +"cookie@npm:1.0.1": + version: 1.0.1 + resolution: "cookie@npm:1.0.1" + checksum: 10/4b24d4fad5ba94ab76d74a8fc33ae1dcdb5dc02013e03e9577b26f019d9dfe396ffb9b3711ba1726bcfa1b93c33d117db0f31e187838aed7753dee1abc691688 + languageName: node + linkType: hard + +"cookie@npm:^0.6.0": version: 0.6.0 resolution: "cookie@npm:0.6.0" checksum: 10/c1f8f2ea7d443b9331680598b0ae4e6af18a618c37606d1bbdc75bec8361cce09fe93e727059a673f2ba24467131a9fb5a4eec76bb1b149c1b3e1ccb268dc583 @@ -8941,10 +8814,10 @@ __metadata: languageName: node linkType: hard -"d3-hierarchy@npm:^3.1.2": - version: 3.1.2 - resolution: "d3-hierarchy@npm:3.1.2" - checksum: 10/497b79dc6c35e28b21e8a7b94db92876abd1d4ec082d9803a07ea8964e55b0e71c511a21489363a36f1456f069adb8ff7d33c633678730d6ae961ed350b27733 +"d3-hierarchy@npm:^1.1.9": + version: 1.1.9 + resolution: "d3-hierarchy@npm:1.1.9" + checksum: 10/d2a4e518c3e35de15e0ac7f0a420300a658435850fc32eaf15b7811697e34565b89012e07e60a53babb723dc43df8981102079b4097b790b42ac21c8d23c0424 languageName: node linkType: hard @@ -8957,6 +8830,13 @@ __metadata: languageName: node linkType: hard +"d3-path@npm:1": + version: 1.0.9 + resolution: "d3-path@npm:1.0.9" + checksum: 10/6ce1747837ea2a449d9ea32e169a382978ab09a4805eb408feb6bbc12cb5f5f6ce29aefc252dd9a815d420f4813d672f75578b78b3bbaf7811f54d8c7f93fd11 + languageName: node + linkType: hard + "d3-path@npm:^3.1.0": version: 3.1.0 resolution: "d3-path@npm:3.1.0" @@ -8984,7 +8864,16 @@ __metadata: languageName: node linkType: hard -"d3-shape@npm:^3.1.0, d3-shape@npm:^3.2.0": +"d3-shape@npm:^1.3.7": + version: 1.3.7 + resolution: "d3-shape@npm:1.3.7" + dependencies: + d3-path: "npm:1" + checksum: 10/1e40fdcfdc8edc9c53a77a6aaea2dbf31bf06df12ebd66cc8d91f76bbde753049ad21dfee0577f7dc5d0a4468554ede4783f6df7d809e291745334dba977c09e + languageName: node + linkType: hard + +"d3-shape@npm:^3.1.0": version: 3.2.0 resolution: "d3-shape@npm:3.2.0" dependencies: @@ -9060,19 +8949,10 @@ __metadata: languageName: node linkType: hard -"date-fns@npm:^2.30.0": - version: 2.30.0 - resolution: "date-fns@npm:2.30.0" - dependencies: - "@babel/runtime": "npm:^7.21.0" - checksum: 10/70b3e8ea7aaaaeaa2cd80bd889622a4bcb5d8028b4de9162cbcda359db06e16ff6e9309e54eead5341e71031818497f19aaf9839c87d1aba1e27bb4796e758a9 - languageName: node - linkType: hard - -"dayjs@npm:1.11.12": - version: 1.11.12 - resolution: "dayjs@npm:1.11.12" - checksum: 10/8ee7c1e14961fd08d40b788d0c0e930dc6288b3d32911bb911b2fb31bb703c262788164fbe678ee9e50e2a35268d667b8c8ba43fd1806771c1f404c300a2b428 +"date-fns@npm:^4.1.0": + version: 4.1.0 + resolution: "date-fns@npm:4.1.0" + checksum: 10/d5f6e9de5bbc52310f786099e18609289ed5e30af60a71e0646784c8185ddd1d0eebcf7c96b7faaaefc4a8366f3a3a4244d099b6d0866ee2bec80d1361e64342 languageName: node linkType: hard @@ -9206,6 +9086,17 @@ __metadata: languageName: node linkType: hard +"define-data-property@npm:^1.1.4": + version: 1.1.4 + resolution: "define-data-property@npm:1.1.4" + dependencies: + es-define-property: "npm:^1.0.0" + es-errors: "npm:^1.3.0" + gopd: "npm:^1.0.1" + checksum: 10/abdcb2505d80a53524ba871273e5da75e77e52af9e15b3aa65d8aad82b8a3a424dad7aee2cc0b71470ac7acf501e08defac362e8b6a73cdb4309f028061df4ae + languageName: node + linkType: hard + "delayed-stream@npm:~1.0.0": version: 1.0.0 resolution: "delayed-stream@npm:1.0.0" @@ -9234,7 +9125,7 @@ __metadata: languageName: node linkType: hard -"dequal@npm:^2.0.0": +"dequal@npm:^2.0.0, dequal@npm:^2.0.2": version: 2.0.3 resolution: "dequal@npm:2.0.3" checksum: 10/6ff05a7561f33603df87c45e389c9ac0a95e3c056be3da1a0c4702149e3a7f6fe5ffbb294478687ba51a9e95f3a60e8b6b9005993acd79c292c7d15f71964b6b @@ -9299,6 +9190,15 @@ __metadata: languageName: node linkType: hard +"dom-helpers@npm:^3.3.1": + version: 3.4.0 + resolution: "dom-helpers@npm:3.4.0" + dependencies: + "@babel/runtime": "npm:^7.1.2" + checksum: 10/63ce62469be8cb481c41811f6b463a1b071dce8a7cd73a39cd4fdaa1e570201af6e7a895a502f4db414e2cc0533e44096ad95c13f303e5a3c3a036f0a43798e4 + languageName: node + linkType: hard + "dom-helpers@npm:^5.0.1": version: 5.2.1 resolution: "dom-helpers@npm:5.2.1" @@ -9378,27 +9278,29 @@ __metadata: languageName: node linkType: hard -"drizzle-kit@npm:0.23.0": - version: 0.23.0 - resolution: "drizzle-kit@npm:0.23.0" +"drizzle-kit@npm:0.26.2": + version: 0.26.2 + resolution: "drizzle-kit@npm:0.26.2" dependencies: + "@drizzle-team/brocli": "npm:^0.10.1" "@esbuild-kit/esm-loader": "npm:^2.5.5" esbuild: "npm:^0.19.7" esbuild-register: "npm:^3.5.0" bin: drizzle-kit: bin.cjs - checksum: 10/e1e2403e1deed9dd9bfd96e100860c658b44d11ea50659e21c328640f22e6ec89a05345a09af8d94913a526a23693aa244d0964bdd30658bdb2ec6ec4998128d + checksum: 10/6d499a9a55761efa42c37e1416905a8c53602784ee92526af226060fc96736dc758c56cc2327432e7892278015f342d1da0eb814a0336f0f4ea85a836ab6c82e languageName: node linkType: hard -"drizzle-orm@npm:0.32.1": - version: 0.32.1 - resolution: "drizzle-orm@npm:0.32.1" +"drizzle-orm@npm:0.35.3": + version: 0.35.3 + resolution: "drizzle-orm@npm:0.35.3" peerDependencies: "@aws-sdk/client-rds-data": ">=3" "@cloudflare/workers-types": ">=3" "@electric-sql/pglite": ">=0.1.1" - "@libsql/client": "*" + "@libsql/client": ">=0.10.0" + "@libsql/client-wasm": ">=0.10.0" "@neondatabase/serverless": ">=0.1" "@op-engineering/op-sqlite": ">=2" "@opentelemetry/api": ^1.4.1 @@ -9479,7 +9381,7 @@ __metadata: optional: true sqlite3: optional: true - checksum: 10/a17a0bf757b67606d44fd938e89670b1595a75258a7685e642e428a64a0e6c867322da327312ff68b1f2439b1a4059cff8588108b369328309738910cc2c7697 + checksum: 10/d91b5bb85983508e838e12f75b5463ca87b4dad31e55026dfeeeba9153226d86eb7743b8cedc0a7c8e609e2930f4b7ffff426416c4a939dd0f0e6b6c581b39f0 languageName: node linkType: hard @@ -9541,17 +9443,6 @@ __metadata: languageName: node linkType: hard -"ejs@npm:^3.1.9": - version: 3.1.9 - resolution: "ejs@npm:3.1.9" - dependencies: - jake: "npm:^10.8.5" - bin: - ejs: bin/cli.js - checksum: 10/71f56d37540d2c2d71701f0116710c676f75314a3e997ef8b83515d5d4d2b111c5a72725377caeecb928671bacb84a0d38135f345904812e989847057d59f21a - languageName: node - linkType: hard - "electron-to-chromium@npm:^1.4.284": version: 1.4.356 resolution: "electron-to-chromium@npm:1.4.356" @@ -9573,12 +9464,19 @@ __metadata: languageName: node linkType: hard -"embla-carousel-autoplay@npm:8.1.7": - version: 8.1.7 - resolution: "embla-carousel-autoplay@npm:8.1.7" +"electron-to-chromium@npm:^1.5.41": + version: 1.5.42 + resolution: "electron-to-chromium@npm:1.5.42" + checksum: 10/869d4813723980a3566b45b0550a99cf46467db3464e9b45b3aad116989faf36bf62c8e73cf25956435fb814e9f8b6bcace4c17f6ecc315df87fbfb5518664ff + languageName: node + linkType: hard + +"embla-carousel-autoplay@npm:8.3.0": + version: 8.3.0 + resolution: "embla-carousel-autoplay@npm:8.3.0" peerDependencies: - embla-carousel: 8.1.7 - checksum: 10/8abc97d3405a55377813f247ccc040db94e6994a36b69a0a4c8017973376b4ed056d5501f085af0b051b815b0d55e7f9a360e7fa53e21c2919eba194976f6833 + embla-carousel: 8.3.0 + checksum: 10/1e891db0d341bbe31d7315d53b3e96d970a1df632db98d9bcaf5b44829311d592fb742afa09f9ece1a7fd898f440a8da13161e0974451a344bbeb265a8e80f05 languageName: node linkType: hard @@ -9593,24 +9491,24 @@ __metadata: languageName: node linkType: hard -"embla-carousel-react@npm:8.1.7": - version: 8.1.7 - resolution: "embla-carousel-react@npm:8.1.7" +"embla-carousel-react@npm:8.3.0": + version: 8.3.0 + resolution: "embla-carousel-react@npm:8.3.0" dependencies: - embla-carousel: "npm:8.1.7" - embla-carousel-reactive-utils: "npm:8.1.7" + embla-carousel: "npm:8.3.0" + embla-carousel-reactive-utils: "npm:8.3.0" peerDependencies: react: ^16.8.0 || ^17.0.1 || ^18.0.0 - checksum: 10/623a903e04d4707dabb8e7ce18b326be610b0394eb9237a78c738477c945f32fee4b5a3681289227080ace467a037ea5fabdae2f36cc8c02a9e5afc0e421308a + checksum: 10/48b71504208741d051f09d26ec7925c4470c0c7b9dce1275079d1ab1a32f7892456b953df2836f1be7555061aaac595509d78ab12c0e1370dd7f77df682639f6 languageName: node linkType: hard -"embla-carousel-reactive-utils@npm:8.1.7": - version: 8.1.7 - resolution: "embla-carousel-reactive-utils@npm:8.1.7" +"embla-carousel-reactive-utils@npm:8.3.0": + version: 8.3.0 + resolution: "embla-carousel-reactive-utils@npm:8.3.0" peerDependencies: - embla-carousel: 8.1.7 - checksum: 10/ad6b24dca37e7918dae32cc490e2fdcfa2ccbbc9f3059c7c76fd3b0ce8e5e2d6e9aa5fcd5338a20cf6908ae7dffeeec7547c798acda8bb7011ddfbb148a6f965 + embla-carousel: 8.3.0 + checksum: 10/8d1db9a65455dbbee4de7e163c470b2a7552dee13153e95c8754d37389e29dbd03b9a7b11018c84ed59b4db616846cf39de8ea828f50945ab9ea1e99fe9e7289 languageName: node linkType: hard @@ -9621,10 +9519,10 @@ __metadata: languageName: node linkType: hard -"embla-carousel@npm:8.1.7": - version: 8.1.7 - resolution: "embla-carousel@npm:8.1.7" - checksum: 10/9721d494c35a576254eb69d3d6cc6dea320a335ffd45dd1c71be54af29e5d2db616777d3808affad209cc4c5a1e488a0f2fc641ef8df83ea0f28c9720bf2c464 +"embla-carousel@npm:8.3.0": + version: 8.3.0 + resolution: "embla-carousel@npm:8.3.0" + checksum: 10/939db8fbe604f1d46a1c3150bf8be7f5a566924e426a02762c0c97dcf474973fdb128a113d96a57e953753657fb69298f31247e7dfbc4d820fbb691c54502249 languageName: node linkType: hard @@ -9649,6 +9547,13 @@ __metadata: languageName: node linkType: hard +"encodeurl@npm:~2.0.0": + version: 2.0.0 + resolution: "encodeurl@npm:2.0.0" + checksum: 10/abf5cd51b78082cf8af7be6785813c33b6df2068ce5191a40ca8b1afe6a86f9230af9a9ce694a5ce4665955e5c1120871826df9c128a642e09c58d592e2807fe + languageName: node + linkType: hard + "encoding@npm:^0.1.13": version: 0.1.13 resolution: "encoding@npm:0.1.13" @@ -9705,7 +9610,7 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.17.0": +"enhanced-resolve@npm:^5.17.1": version: 5.17.1 resolution: "enhanced-resolve@npm:5.17.1" dependencies: @@ -9756,6 +9661,22 @@ __metadata: languageName: node linkType: hard +"es-define-property@npm:^1.0.0": + version: 1.0.0 + resolution: "es-define-property@npm:1.0.0" + dependencies: + get-intrinsic: "npm:^1.2.4" + checksum: 10/f66ece0a887b6dca71848fa71f70461357c0e4e7249696f81bad0a1f347eed7b31262af4a29f5d726dc026426f085483b6b90301855e647aa8e21936f07293c6 + languageName: node + linkType: hard + +"es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: 10/96e65d640156f91b707517e8cdc454dd7d47c32833aa3e85d79f24f9eb7ea85f39b63e36216ef0114996581969b59fe609a94e30316b08f5f4df1d44134cf8d5 + languageName: node + linkType: hard + "es-module-lexer@npm:^1.2.1, es-module-lexer@npm:^1.4.1": version: 1.5.4 resolution: "es-module-lexer@npm:1.5.4" @@ -10028,7 +9949,7 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.19.3, esbuild@npm:^0.19.7": +"esbuild@npm:^0.19.7": version: 0.19.12 resolution: "esbuild@npm:0.19.12" dependencies: @@ -10202,6 +10123,13 @@ __metadata: languageName: node linkType: hard +"escalade@npm:^3.2.0": + version: 3.2.0 + resolution: "escalade@npm:3.2.0" + checksum: 10/9d7169e3965b2f9ae46971afa392f6e5a25545ea30f2e2dd99c9b0a95a3f52b5653681a84f5b2911a413ddad2d7a93d3514165072f349b5ffc59c75a899970d6 + languageName: node + linkType: hard + "escape-html@npm:~1.0.3": version: 1.0.3 resolution: "escape-html@npm:1.0.3" @@ -10431,42 +10359,42 @@ __metadata: languageName: node linkType: hard -"express@npm:^4.19.2": - version: 4.19.2 - resolution: "express@npm:4.19.2" +"express@npm:^4.20.0": + version: 4.21.1 + resolution: "express@npm:4.21.1" dependencies: accepts: "npm:~1.3.8" array-flatten: "npm:1.1.1" - body-parser: "npm:1.20.2" + body-parser: "npm:1.20.3" content-disposition: "npm:0.5.4" content-type: "npm:~1.0.4" - cookie: "npm:0.6.0" + cookie: "npm:0.7.1" cookie-signature: "npm:1.0.6" debug: "npm:2.6.9" depd: "npm:2.0.0" - encodeurl: "npm:~1.0.2" + encodeurl: "npm:~2.0.0" escape-html: "npm:~1.0.3" etag: "npm:~1.8.1" - finalhandler: "npm:1.2.0" + finalhandler: "npm:1.3.1" fresh: "npm:0.5.2" http-errors: "npm:2.0.0" - merge-descriptors: "npm:1.0.1" + merge-descriptors: "npm:1.0.3" methods: "npm:~1.1.2" on-finished: "npm:2.4.1" parseurl: "npm:~1.3.3" - path-to-regexp: "npm:0.1.7" + path-to-regexp: "npm:0.1.10" proxy-addr: "npm:~2.0.7" - qs: "npm:6.11.0" + qs: "npm:6.13.0" range-parser: "npm:~1.2.1" safe-buffer: "npm:5.2.1" - send: "npm:0.18.0" - serve-static: "npm:1.15.0" + send: "npm:0.19.0" + serve-static: "npm:1.16.2" setprototypeof: "npm:1.2.0" statuses: "npm:2.0.1" type-is: "npm:~1.6.18" utils-merge: "npm:1.0.1" vary: "npm:~1.1.2" - checksum: 10/3fcd792536f802c059789ef48db3851b87e78fba103423e524144d79af37da7952a2b8d4e1a007f423329c7377d686d9476ac42e7d9ea413b80345d495e30a3a + checksum: 10/5d4a36dd03c1d1cce93172e9b185b5cd13a978d29ee03adc51cd278be7b4a514ae2b63e2fdaec0c00fdc95c6cfb396d9dd1da147917ffd337d6cd0778e08c9bc languageName: node linkType: hard @@ -10654,10 +10582,10 @@ __metadata: languageName: node linkType: hard -"filesize@npm:10.1.4": - version: 10.1.4 - resolution: "filesize@npm:10.1.4" - checksum: 10/ac2b95f4ee8d42ad4b12f8f918baeb1127065dcb319abca30c0d9ef115b602e31a06c8150953b13dc52e52ebb1238e18e6001ab5fca14a10957e788bd6012f1c +"filesize@npm:10.1.6": + version: 10.1.6 + resolution: "filesize@npm:10.1.6" + checksum: 10/e800837c4fc02303f1944d5a4c7b706df1c5cd95d745181852604fb00a1c2d55d2d3921252722bd2f0c86b59c94edaba23fa224776bbf977455d4034e7be1f45 languageName: node linkType: hard @@ -10670,18 +10598,18 @@ __metadata: languageName: node linkType: hard -"finalhandler@npm:1.2.0": - version: 1.2.0 - resolution: "finalhandler@npm:1.2.0" +"finalhandler@npm:1.3.1": + version: 1.3.1 + resolution: "finalhandler@npm:1.3.1" dependencies: debug: "npm:2.6.9" - encodeurl: "npm:~1.0.2" + encodeurl: "npm:~2.0.0" escape-html: "npm:~1.0.3" on-finished: "npm:2.4.1" parseurl: "npm:~1.3.3" statuses: "npm:2.0.1" unpipe: "npm:~1.0.0" - checksum: 10/635718cb203c6d18e6b48dfbb6c54ccb08ea470e4f474ddcef38c47edcf3227feec316f886dd701235997d8af35240cae49856721ce18f539ad038665ebbf163 + checksum: 10/4babe72969b7373b5842bc9f75c3a641a4d0f8eb53af6b89fa714d4460ce03fb92b28de751d12ba415e96e7e02870c436d67412120555e2b382640535697305b languageName: node linkType: hard @@ -10970,6 +10898,19 @@ __metadata: languageName: node linkType: hard +"get-intrinsic@npm:^1.2.4": + version: 1.2.4 + resolution: "get-intrinsic@npm:1.2.4" + dependencies: + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + has-proto: "npm:^1.0.1" + has-symbols: "npm:^1.0.3" + hasown: "npm:^2.0.0" + checksum: 10/85bbf4b234c3940edf8a41f4ecbd4e25ce78e5e6ad4e24ca2f77037d983b9ef943fd72f00f3ee97a49ec622a506b67db49c36246150377efcda1c9eb03e5f06d + languageName: node + linkType: hard + "get-nonce@npm:^1.0.0": version: 1.0.1 resolution: "get-nonce@npm:1.0.1" @@ -11151,9 +11092,9 @@ __metadata: languageName: node linkType: hard -"graphql-config@npm:^5.0.2": - version: 5.0.2 - resolution: "graphql-config@npm:5.0.2" +"graphql-config@npm:^5.1.1": + version: 5.1.3 + resolution: "graphql-config@npm:5.1.3" dependencies: "@graphql-tools/graphql-file-loader": "npm:^8.0.0" "@graphql-tools/json-file-loader": "npm:^8.0.0" @@ -11162,8 +11103,8 @@ __metadata: "@graphql-tools/url-loader": "npm:^8.0.0" "@graphql-tools/utils": "npm:^10.0.0" cosmiconfig: "npm:^8.1.0" - jiti: "npm:^1.18.2" - minimatch: "npm:^4.2.3" + jiti: "npm:^2.0.0" + minimatch: "npm:^9.0.5" string-env-interpolation: "npm:^1.0.1" tslib: "npm:^2.4.0" peerDependencies: @@ -11172,7 +11113,7 @@ __metadata: peerDependenciesMeta: cosmiconfig-toml-loader: optional: true - checksum: 10/668f177e8c36e482b246ec84e10e0e9d7f29e51b519828d22866c724500cf2cc075a07e4d5d5f057df9eaa189550d485072d3814b15ff0b383367e0fa92f8bbf + checksum: 10/9d37f5d424f302808102d118988878be5e4841ba1a06a865cdb9052b24e26eaa9923fb18163bf4f32102d87b3895c53e2ffcdebc1d651f04b56f93f5c38b83c3 languageName: node linkType: hard @@ -11286,6 +11227,15 @@ __metadata: languageName: node linkType: hard +"has-property-descriptors@npm:^1.0.2": + version: 1.0.2 + resolution: "has-property-descriptors@npm:1.0.2" + dependencies: + es-define-property: "npm:^1.0.0" + checksum: 10/2d8c9ab8cebb572e3362f7d06139a4592105983d4317e68f7adba320fe6ddfc8874581e0971e899e633fd5f72e262830edce36d5a0bc863dad17ad20572484b2 + languageName: node + linkType: hard + "has-proto@npm:^1.0.1": version: 1.0.1 resolution: "has-proto@npm:1.0.1" @@ -11374,15 +11324,6 @@ __metadata: languageName: node linkType: hard -"hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.2": - version: 3.3.2 - resolution: "hoist-non-react-statics@npm:3.3.2" - dependencies: - react-is: "npm:^16.7.0" - checksum: 10/1acbe85f33e5a39f90c822ad4d28b24daeb60f71c545279431dc98c312cd28a54f8d64788e477fe21dc502b0e3cf58589ebe5c1ad22af27245370391c2d24ea6 - languageName: node - linkType: hard - "hosted-git-info@npm:^2.1.4": version: 2.8.9 resolution: "hosted-git-info@npm:2.8.9" @@ -12028,13 +11969,6 @@ __metadata: languageName: node linkType: hard -"isbot@npm:4.1.0": - version: 4.1.0 - resolution: "isbot@npm:4.1.0" - checksum: 10/ee76a2c937e701dbc47043fe71ab887dd3e7a5ba7c61f12bb7053b5634c1e3d413325f1adee3bc615cb8b75b9a95e9c79f36c66f11809cc4108488cb8e21d1dc - languageName: node - linkType: hard - "isbot@npm:5.1.17": version: 5.1.17 resolution: "isbot@npm:5.1.17" @@ -12125,15 +12059,6 @@ __metadata: languageName: node linkType: hard -"jiti@npm:^1.18.2": - version: 1.19.1 - resolution: "jiti@npm:1.19.1" - bin: - jiti: bin/jiti.js - checksum: 10/88f11b406a877db348b956eb9cecf42d6cb6edcd6317aa75c032130fc88c1150baf8def5511e808af10b11336db2639a295ffe1ed455d65216dcef45a0a424b5 - languageName: node - linkType: hard - "jiti@npm:^1.19.1, jiti@npm:^1.21.0": version: 1.21.6 resolution: "jiti@npm:1.21.6" @@ -12143,6 +12068,15 @@ __metadata: languageName: node linkType: hard +"jiti@npm:^2.0.0": + version: 2.3.3 + resolution: "jiti@npm:2.3.3" + bin: + jiti: lib/jiti-cli.mjs + checksum: 10/21d1e89d909101c702769537e75ad87b433f980bc6938a6f64a90d1fbe7cb1510a0d4b82d4020b3093b47cebff5568af5e39d883e26aa4413564ced43b8cfd84 + languageName: node + linkType: hard + "jose@npm:^4.11.4": version: 4.14.0 resolution: "jose@npm:4.14.0" @@ -12157,9 +12091,9 @@ __metadata: languageName: node linkType: hard -"jotai@npm:2.9.3": - version: 2.9.3 - resolution: "jotai@npm:2.9.3" +"jotai@npm:2.10.1": + version: 2.10.1 + resolution: "jotai@npm:2.10.1" peerDependencies: "@types/react": ">=17.0.0" react: ">=17.0.0" @@ -12168,7 +12102,7 @@ __metadata: optional: true react: optional: true - checksum: 10/4366a50be8edd39f1430ac655677e559cfbb253101e4f2e750bca8ebd81e75ea09ea3828bce727482b15305ffe924dda75bd9a055e903e0cc804b6600478dc36 + checksum: 10/6d01b3daa88d9edbce06776fb70921f7341c5bd5787cd3d3dd91a820760838ebe5abafe7563f0d04957a1d863b557999260ad33d225ce1d54e5fdd9a1a93af0e languageName: node linkType: hard @@ -12544,7 +12478,7 @@ __metadata: languageName: node linkType: hard -"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -12612,12 +12546,12 @@ __metadata: languageName: node linkType: hard -"lucide-react@npm:0.414.0": - version: 0.414.0 - resolution: "lucide-react@npm:0.414.0" +"lucide-react@npm:0.453.0": + version: 0.453.0 + resolution: "lucide-react@npm:0.453.0" peerDependencies: - react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 - checksum: 10/d2524481f14f690e15add2a517d5bcda1432029ae212e82fa8e8624bec0501f8131514d0a03519a60d9d543252f33d8ab0e7a592dee365ec9cc49fe403d5ff1b + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc + checksum: 10/b49c486ce04ebe3650d756aab0584eb96d4b3c2381ab1185ebedbd00333cfafcfe71766f918bc5ea7538bab0339804363afa5503acb416ee2208af9d31a9fac1 languageName: node linkType: hard @@ -12664,15 +12598,15 @@ __metadata: languageName: node linkType: hard -"mantine-datatable@npm:7.11.3": - version: 7.11.3 - resolution: "mantine-datatable@npm:7.11.3" +"mantine-datatable@npm:7.12.4": + version: 7.12.4 + resolution: "mantine-datatable@npm:7.12.4" peerDependencies: - "@mantine/core": ">=7.8" - "@mantine/hooks": ">=7.8" + "@mantine/core": ">=7.11" + "@mantine/hooks": ">=7.11" clsx: ">=2" react: ">=18.2" - checksum: 10/8fe7c5745ed3ec8278ca52d19b0826d5437d32e5973d2f11d5fb05152e1a8fe47decf8010a9ba3ef1e47f8784742044bd06b4059c8ddb787f141b98ecfbea104 + checksum: 10/01ea1fb8425ee36eee35db73ec41a8b1f2ecb57e5ff039e1fdc0f03d8cd2d7ccd047b9a37ec3821d5b8c4b3787f6b8599788a61cba06109cccdf1126b1213950 languageName: node linkType: hard @@ -12919,10 +12853,10 @@ __metadata: languageName: node linkType: hard -"merge-descriptors@npm:1.0.1": - version: 1.0.1 - resolution: "merge-descriptors@npm:1.0.1" - checksum: 10/5abc259d2ae25bb06d19ce2b94a21632583c74e2a9109ee1ba7fd147aa7362b380d971e0251069f8b3eb7d48c21ac839e21fa177b335e82c76ec172e30c31a26 +"merge-descriptors@npm:1.0.3": + version: 1.0.3 + resolution: "merge-descriptors@npm:1.0.3" + checksum: 10/52117adbe0313d5defa771c9993fe081e2d2df9b840597e966aadafde04ae8d0e3da46bac7ca4efc37d4d2b839436582659cd49c6a43eacb3fe3050896a105d1 languageName: node linkType: hard @@ -13373,21 +13307,12 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": - version: 3.1.2 - resolution: "minimatch@npm:3.1.2" - dependencies: - brace-expansion: "npm:^1.1.7" - checksum: 10/e0b25b04cd4ec6732830344e5739b13f8690f8a012d73445a4a19fbc623f5dd481ef7a5827fde25954cd6026fede7574cc54dc4643c99d6c6b653d6203f94634 - languageName: node - linkType: hard - -"minimatch@npm:^4.2.3": - version: 4.2.3 - resolution: "minimatch@npm:4.2.3" +"minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": + version: 3.1.2 + resolution: "minimatch@npm:3.1.2" dependencies: brace-expansion: "npm:^1.1.7" - checksum: 10/02bacb187448c6aeeed5a794a64799fb1d1dd0274694da97272a9d3b919c7dfba6987d2089f6465191450d36d767c47fd7958227610b919121ccaed7de7f8924 + checksum: 10/e0b25b04cd4ec6732830344e5739b13f8690f8a012d73445a4a19fbc623f5dd481ef7a5827fde25954cd6026fede7574cc54dc4643c99d6c6b653d6203f94634 languageName: node linkType: hard @@ -13409,7 +13334,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^9.0.4": +"minimatch@npm:^9.0.4, minimatch@npm:^9.0.5": version: 9.0.5 resolution: "minimatch@npm:9.0.5" dependencies: @@ -13824,6 +13749,13 @@ __metadata: languageName: node linkType: hard +"node-releases@npm:^2.0.18": + version: 2.0.18 + resolution: "node-releases@npm:2.0.18" + checksum: 10/241e5fa9556f1c12bafb83c6c3e94f8cf3d8f2f8f904906ecef6e10bcaa1d59aa61212d4651bec70052015fc54bd3fdcdbe7fc0f638a17e6685aa586c076ec4e + languageName: node + linkType: hard + "node-releases@npm:^2.0.8": version: 2.0.10 resolution: "node-releases@npm:2.0.10" @@ -13831,10 +13763,10 @@ __metadata: languageName: node linkType: hard -"nodemailer@npm:6.9.14": - version: 6.9.14 - resolution: "nodemailer@npm:6.9.14" - checksum: 10/749d1a3ef440d6147c37ad850f5be065d55d87cd46a4470372d4e443593838a5ddd78c69623817a804ddede3212fa28ac069b5b8266e892b27e1dcff75103def +"nodemailer@npm:6.9.15": + version: 6.9.15 + resolution: "nodemailer@npm:6.9.15" + checksum: 10/16079406fe603f6e4debb8ac34bdb919688ad169ddf61e7b10e56abef85b537762eb3a19a15ce32bb9446d68e2f93a1ba4e24836ba86c7363fc42145aa36a291 languageName: node linkType: hard @@ -14008,10 +13940,10 @@ __metadata: languageName: node linkType: hard -"object-inspect@npm:^1.9.0": - version: 1.12.3 - resolution: "object-inspect@npm:1.12.3" - checksum: 10/532b0036f0472f561180fac0d04fe328ee01f57637624c83fb054f81b5bfe966cdf4200612a499ed391a7ca3c46b20a0bc3a55fc8241d944abe687c556a32b39 +"object-inspect@npm:^1.13.1": + version: 1.13.2 + resolution: "object-inspect@npm:1.13.2" + checksum: 10/7ef65583b6397570a17c56f0c1841e0920e83900f2c94638927abb7b81ac08a19c7aae135bd9dcca96208cac0c7332b4650fb927f027b0cf92d71df2990d0561 languageName: node linkType: hard @@ -14354,10 +14286,10 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:0.1.7": - version: 0.1.7 - resolution: "path-to-regexp@npm:0.1.7" - checksum: 10/701c99e1f08e3400bea4d701cf6f03517474bb1b608da71c78b1eb261415b645c5670dfae49808c89e12cea2dccd113b069f040a80de012da0400191c6dbd1c8 +"path-to-regexp@npm:0.1.10": + version: 0.1.10 + resolution: "path-to-regexp@npm:0.1.10" + checksum: 10/894e31f1b20e592732a87db61fff5b95c892a3fe430f9ab18455ebe69ee88ef86f8eb49912e261f9926fc53da9f93b46521523e33aefd9cb0a7b0d85d7096006 languageName: node linkType: hard @@ -14425,6 +14357,13 @@ __metadata: languageName: node linkType: hard +"picocolors@npm:^1.1.0": + version: 1.1.1 + resolution: "picocolors@npm:1.1.1" + checksum: 10/e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045 + languageName: node + linkType: hard + "picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.3.1": version: 2.3.1 resolution: "picomatch@npm:2.3.1" @@ -14723,14 +14662,14 @@ __metadata: languageName: node linkType: hard -"postcss@npm:8.4.41, postcss@npm:^8.4.41": - version: 8.4.41 - resolution: "postcss@npm:8.4.41" +"postcss@npm:8.4.47, postcss@npm:^8.4.43": + version: 8.4.47 + resolution: "postcss@npm:8.4.47" dependencies: nanoid: "npm:^3.3.7" - picocolors: "npm:^1.0.1" - source-map-js: "npm:^1.2.0" - checksum: 10/6e6176c2407eff60493ca60a706c6b7def20a722c3adda94ea1ece38345eb99964191336fd62b62652279cec6938e79e0b1e1d477142c8d3516e7a725a74ee37 + picocolors: "npm:^1.1.0" + source-map-js: "npm:^1.2.1" + checksum: 10/f2b50ba9b6fcb795232b6bb20de7cdc538c0025989a8ed9c4438d1960196ba3b7eaff41fdb1a5c701b3504651ea87aeb685577707f0ae4d6ce6f3eae5df79a81 languageName: node linkType: hard @@ -14840,7 +14779,7 @@ __metadata: languageName: node linkType: hard -"prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": +"prop-types@npm:^15.5.6, prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": version: 15.8.1 resolution: "prop-types@npm:15.8.1" dependencies: @@ -14934,28 +14873,12 @@ __metadata: languageName: node linkType: hard -"pvtsutils@npm:^1.3.2": - version: 1.3.2 - resolution: "pvtsutils@npm:1.3.2" - dependencies: - tslib: "npm:^2.4.0" - checksum: 10/3e89fea1836dd9027446d65923f7240372a1040b777b2e6adfc319bfeb3cacfd56dccb708652651e85ad6a5c87f61728b697226c105d441140b648f3e4167872 - languageName: node - linkType: hard - -"pvutils@npm:^1.1.3": - version: 1.1.3 - resolution: "pvutils@npm:1.1.3" - checksum: 10/e5201b8f78ece68eae414a938c844bc45fb3f0de298178eed1775a217eedfd897c4346e5e54f410bb4d7466e09ceb262e85f20fd64239b8bb2595f14c52fa95e - languageName: node - linkType: hard - -"qs@npm:6.11.0": - version: 6.11.0 - resolution: "qs@npm:6.11.0" +"qs@npm:6.13.0": + version: 6.13.0 + resolution: "qs@npm:6.13.0" dependencies: - side-channel: "npm:^1.0.4" - checksum: 10/5a3bfea3e2f359ede1bfa5d2f0dbe54001aa55e40e27dc3e60fab814362d83a9b30758db057c2011b6f53a2d4e4e5150194b5bac45372652aecb3e3c0d4b256e + side-channel: "npm:^1.0.6" + checksum: 10/f548b376e685553d12e461409f0d6e5c59ec7c7d76f308e2a888fd9db3e0c5e89902bedd0754db3a9038eda5f27da2331a6f019c8517dc5e0a16b3c9a6e9cef8 languageName: node linkType: hard @@ -15018,6 +14941,26 @@ __metadata: languageName: node linkType: hard +"react-d3-tree@npm:^3.6.2": + version: 3.6.2 + resolution: "react-d3-tree@npm:3.6.2" + dependencies: + "@bkrem/react-transition-group": "npm:^1.3.3" + "@types/d3-hierarchy": "npm:^1.1.8" + clone: "npm:^2.1.1" + d3-hierarchy: "npm:^1.1.9" + d3-selection: "npm:^3.0.0" + d3-shape: "npm:^1.3.7" + d3-zoom: "npm:^3.0.0" + dequal: "npm:^2.0.2" + uuid: "npm:^8.3.1" + peerDependencies: + react: 16.x || 17.x || 18.x + react-dom: 16.x || 17.x || 18.x + checksum: 10/cb8b9e8ea4a17561c867733c4dbc3ee0d51593a7b9777f2100ef9574ddeaebc7ea2b29f17ab69d7b699883dc443f7d93e2b42af62c739f750c679e8f1322750d + languageName: node + linkType: hard + "react-diff-viewer-continued@npm:^3.3.1": version: 3.4.0 resolution: "react-diff-viewer-continued@npm:3.4.0" @@ -15034,18 +14977,6 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:18.2.0": - version: 18.2.0 - resolution: "react-dom@npm:18.2.0" - dependencies: - loose-envify: "npm:^1.1.0" - scheduler: "npm:^0.23.0" - peerDependencies: - react: ^18.2.0 - checksum: 10/ca5e7762ec8c17a472a3605b6f111895c9f87ac7d43a610ab7024f68cd833d08eda0625ce02ec7178cc1f3c957cf0b9273cdc17aa2cd02da87544331c43b1d21 - languageName: node - linkType: hard - "react-dom@npm:18.3.1, react-dom@npm:^18.2.0": version: 18.3.1 resolution: "react-dom@npm:18.3.1" @@ -15118,17 +15049,24 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^16.10.2, react-is@npm:^16.13.1, react-is@npm:^16.7.0": +"react-is@npm:^16.13.1": version: 16.13.1 resolution: "react-is@npm:16.13.1" checksum: 10/5aa564a1cde7d391ac980bedee21202fc90bdea3b399952117f54fb71a932af1e5902020144fb354b4690b2414a0c7aafe798eb617b76a3d441d956db7726fdf languageName: node linkType: hard -"react-is@npm:^18.0.0": - version: 18.2.0 - resolution: "react-is@npm:18.2.0" - checksum: 10/200cd65bf2e0be7ba6055f647091b725a45dd2a6abef03bf2380ce701fd5edccee40b49b9d15edab7ac08a762bf83cb4081e31ec2673a5bfb549a36ba21570df +"react-is@npm:^18.3.1": + version: 18.3.1 + resolution: "react-is@npm:18.3.1" + checksum: 10/d5f60c87d285af24b1e1e7eaeb123ec256c3c8bdea7061ab3932e3e14685708221bf234ec50b21e10dd07f008f1b966a2730a0ce4ff67905b3872ff2042aec22 + languageName: node + linkType: hard + +"react-lifecycles-compat@npm:^3.0.4": + version: 3.0.4 + resolution: "react-lifecycles-compat@npm:3.0.4" + checksum: 10/c66b9c98c15cd6b0d0a4402df5f665e8cc7562fb7033c34508865bea51fd7b623f7139b5b7e708515d3cd665f264a6a9403e1fa7e6d61a05759066f5e9f07783 languageName: node linkType: hard @@ -15153,35 +15091,22 @@ __metadata: languageName: node linkType: hard -"react-redux@npm:^8.1.3": - version: 8.1.3 - resolution: "react-redux@npm:8.1.3" +"react-redux@npm:^9.1.2": + version: 9.1.2 + resolution: "react-redux@npm:9.1.2" dependencies: - "@babel/runtime": "npm:^7.12.1" - "@types/hoist-non-react-statics": "npm:^3.3.1" "@types/use-sync-external-store": "npm:^0.0.3" - hoist-non-react-statics: "npm:^3.3.2" - react-is: "npm:^18.0.0" use-sync-external-store: "npm:^1.0.0" peerDependencies: - "@types/react": ^16.8 || ^17.0 || ^18.0 - "@types/react-dom": ^16.8 || ^17.0 || ^18.0 - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - react-native: ">=0.59" - redux: ^4 || ^5.0.0-beta.0 + "@types/react": ^18.2.25 + react: ^18.0 + redux: ^5.0.0 peerDependenciesMeta: "@types/react": optional: true - "@types/react-dom": - optional: true - react-dom: - optional: true - react-native: - optional: true redux: optional: true - checksum: 10/c4c7586cff3abeb784e73598d330f5301116a4e9942fd36895f2bccd8990001709c6c3ea1817edb75ee477470d6c67c9113e05a7f86b2b68a3950c9c29fe20cb + checksum: 10/319b3286f538da7e609ca90fc6762ffae007c5cf75e525a25237ac2feaee63d9cf76fe766817de1fc8f27e7bde825ca409c463037d26dd8e57c435d383f80c50 languageName: node linkType: hard @@ -15262,51 +15187,27 @@ __metadata: languageName: node linkType: hard -"react-router-dom@npm:6.25.0": - version: 6.25.0 - resolution: "react-router-dom@npm:6.25.0" - dependencies: - "@remix-run/router": "npm:1.18.0" - react-router: "npm:6.25.0" - peerDependencies: - react: ">=16.8" - react-dom: ">=16.8" - checksum: 10/4f74050c64980a5acd37b62dad2e877b0e757a641b310cb233e8772277e45d60c2e44a75d14572079fee60d5469002b98b46c569761a0b9b347d083804cb3b7b - languageName: node - linkType: hard - -"react-router-dom@npm:6.26.1": - version: 6.26.1 - resolution: "react-router-dom@npm:6.26.1" +"react-router-dom@npm:6.27.0": + version: 6.27.0 + resolution: "react-router-dom@npm:6.27.0" dependencies: - "@remix-run/router": "npm:1.19.1" - react-router: "npm:6.26.1" + "@remix-run/router": "npm:1.20.0" + react-router: "npm:6.27.0" peerDependencies: react: ">=16.8" react-dom: ">=16.8" - checksum: 10/1bd255d1ff88f477699c72656e7c07702a907e644388a1bea1c648f2df0c3c86db2e90bea945b1d43eaf84ebab194f3868f3788502965ad5f20c508c6874f1fe - languageName: node - linkType: hard - -"react-router@npm:6.25.0": - version: 6.25.0 - resolution: "react-router@npm:6.25.0" - dependencies: - "@remix-run/router": "npm:1.18.0" - peerDependencies: - react: ">=16.8" - checksum: 10/7885b90e3abb574b2843b3efefe481ed87c1dba2a17ad301dc0df5e6e93c08c56ccbafc24ee2fc43650e11c1d7d0304762e7c98d43f35e756af76f2587b95b80 + checksum: 10/cfbcbc1d387d3341a335e3a075e487cc09dcbb62f1b83bc827fc3eec937523d5647a2c4488c804dc61581e65561823d0166d17b5dbc8579998c25b5a0bcabad6 languageName: node linkType: hard -"react-router@npm:6.26.1": - version: 6.26.1 - resolution: "react-router@npm:6.26.1" +"react-router@npm:6.27.0": + version: 6.27.0 + resolution: "react-router@npm:6.27.0" dependencies: - "@remix-run/router": "npm:1.19.1" + "@remix-run/router": "npm:1.20.0" peerDependencies: react: ">=16.8" - checksum: 10/b3761515c75da65a1678f005d08a6285ceccd9df7237ae6fdd9ab2ab816ef328435b75610f705ecd9ecd41c6878fd22eb9b44c5391cdef2e1ed99ddbc78de8a4 + checksum: 10/352e3af2075cdccf9d114b7e06d94a1b46a2147ba9d6e8643787a92464f5fd9ead950252a98d551f99f21860288bcf3a4f088cb5f46b28d1274a4e2ba24cc0f9 languageName: node linkType: hard @@ -15369,13 +15270,20 @@ __metadata: languageName: node linkType: hard -"react-virtuoso@npm:4.10.1": - version: 4.10.1 - resolution: "react-virtuoso@npm:4.10.1" +"react-use-websocket@npm:^4.8.1": + version: 4.10.0 + resolution: "react-use-websocket@npm:4.10.0" + checksum: 10/3f03ae19501961efdcefa3ab81e0f80d868f1b5cfe215ad0e35da589ecb4d9747f20504c7f824ab65c80b5231af959b9994785d2284a6024ed205300a930d277 + languageName: node + linkType: hard + +"react-virtuoso@npm:4.12.0": + version: 4.12.0 + resolution: "react-virtuoso@npm:4.12.0" peerDependencies: react: ">=16 || >=17 || >= 18" react-dom: ">=16 || >=17 || >= 18" - checksum: 10/63d77e85c84ce1ecb014ba65e0f353bf1fc108df9f2d071431a088a4964b616f2ceb8dac9458db8bcd7015e93817254a587ccaa5f3a0ebf59606cce526c3adf8 + checksum: 10/f9d899dc7747e475efb793b849de9bac4f71209f3a74238a4d58d7c0c81543cca35179d64029f014fb6ebad2eab18d9a852444a49c8fe7c5177a18f09b9924d4 languageName: node linkType: hard @@ -15389,15 +15297,6 @@ __metadata: languageName: node linkType: hard -"react@npm:18.2.0": - version: 18.2.0 - resolution: "react@npm:18.2.0" - dependencies: - loose-envify: "npm:^1.1.0" - checksum: 10/b9214a9bd79e99d08de55f8bef2b7fc8c39630be97c4e29d7be173d14a9a10670b5325e94485f74cd8bff4966ef3c78ee53c79a7b0b9b70cba20aa8973acc694 - languageName: node - linkType: hard - "react@npm:18.3.1, react@npm:^18.2.0": version: 18.3.1 resolution: "react@npm:18.3.1" @@ -15490,14 +15389,14 @@ __metadata: languageName: node linkType: hard -"recharts@npm:2.12.7": - version: 2.12.7 - resolution: "recharts@npm:2.12.7" +"recharts@npm:2.13.0": + version: 2.13.0 + resolution: "recharts@npm:2.13.0" dependencies: clsx: "npm:^2.0.0" eventemitter3: "npm:^4.0.1" lodash: "npm:^4.17.21" - react-is: "npm:^16.10.2" + react-is: "npm:^18.3.1" react-smooth: "npm:^4.0.0" recharts-scale: "npm:^0.4.4" tiny-invariant: "npm:^1.3.1" @@ -15505,7 +15404,7 @@ __metadata: peerDependencies: react: ^16.0.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 - checksum: 10/dd2806978d025abf37ba6eda36fad9361968257c5224286f2881a9f79b18b6045bab520c9c44fd1dc5bb7e35e7ab51d5cde1669e44cb32610e7cb9c49fdd490f + checksum: 10/d9adf066282c06b1f1b1fbdc69e119060d4b5738b59abba61702afade366023884086d6223c4530279ac3a34f3d81b4626fb5fec099fdeacd16614cb03a861c9 languageName: node linkType: hard @@ -15519,12 +15418,10 @@ __metadata: languageName: node linkType: hard -"redux@npm:^4.2.1": - version: 4.2.1 - resolution: "redux@npm:4.2.1" - dependencies: - "@babel/runtime": "npm:^7.9.2" - checksum: 10/371e4833b671193303a7dea7803c8fdc8e0d566740c78f580e0a3b77b4161da25037626900a2205a5d616117fa6ad09a4232e5a110bd437186b5c6355a041750 +"redux@npm:^5.0.1": + version: 5.0.1 + resolution: "redux@npm:5.0.1" + checksum: 10/a373f9ed65693ead58bea5ef61c1d6bef39da9f2706db3be6f84815f3a1283230ecd1184efb1b3daa7f807d8211b0181564ca8f336fc6ee0b1e2fa0ba06737c2 languageName: node linkType: hard @@ -15624,49 +15521,28 @@ __metadata: languageName: node linkType: hard -"remix-development-tools@npm:4.4.1": - version: 4.4.1 - resolution: "remix-development-tools@npm:4.4.1" +"remix-development-tools@npm:4.7.3": + version: 4.7.3 + resolution: "remix-development-tools@npm:4.7.3" dependencies: "@radix-ui/react-accordion": "npm:^1.1.2" "@radix-ui/react-select": "npm:^1.2.2" beautify: "npm:^0.0.8" chalk: "npm:^5.3.0" - clone: "npm:^2.1.2" clsx: "npm:^2.0.0" - d3-hierarchy: "npm:^3.1.2" - d3-selection: "npm:^3.0.0" - d3-shape: "npm:^3.2.0" - d3-zoom: "npm:^3.0.0" - date-fns: "npm:^2.30.0" + date-fns: "npm:^4.1.0" es-module-lexer: "npm:^1.4.1" + react-d3-tree: "npm:^3.6.2" react-diff-viewer-continued: "npm:^3.3.1" react-hotkeys-hook: "npm:^4.5.0" + react-use-websocket: "npm:^4.8.1" tailwind-merge: "npm:^1.14.0" - uuid: "npm:^9.0.1" - zod: "npm:^3.22.4" peerDependencies: "@remix-run/react": ">=1.15" react: ">=17" react-dom: ">=17" vite: ">=5.0.0" - checksum: 10/cd9f8a51d675edefb58ac3651fbcb6636cb317c1466f6c75d1ce6e641e847b2232e1d051cdaf5b66bda2e3736002764318659c4e2cd8534edcd6b0347decfe21 - languageName: node - linkType: hard - -"remix-routes@npm:1.7.6": - version: 1.7.6 - resolution: "remix-routes@npm:1.7.6" - dependencies: - chokidar: "npm:^3.5.2" - ejs: "npm:^3.1.9" - meow: "npm:9.0.0" - mkdirp: "npm:^1.0.4" - slash: "npm:3" - typescript-remix-routes-plugin: "npm:1.0.1" - bin: - remix-routes: lib/cli.js - checksum: 10/115203419f84a158063b09b07ae80c567b7f6a164cad7a573c3c5f50bd5151e5ce4199175a0fbd50c86a31d1847b5607d43c66e35e7ec3ad337f47f7f1bd12af + checksum: 10/c99e9b2072891db09b24a83e59a379b27f65edfd94c80c04f0da8594ce7778b4ea5cccb0ad1c13fc033b45e62fca45ef4dad6e45ff312b255a265548c3c3740c languageName: node linkType: hard @@ -15685,14 +15561,13 @@ __metadata: languageName: node linkType: hard -"remix-utils@npm:7.6.0": - version: 7.6.0 - resolution: "remix-utils@npm:7.6.0" +"remix-utils@npm:7.7.0": + version: 7.7.0 + resolution: "remix-utils@npm:7.7.0" dependencies: - type-fest: "npm:^4.3.3" + type-fest: "npm:^4.18.1" peerDependencies: "@remix-run/cloudflare": ^2.0.0 - "@remix-run/deno": ^2.0.0 "@remix-run/node": ^2.0.0 "@remix-run/react": ^2.0.0 "@remix-run/router": ^1.7.2 @@ -15704,8 +15579,6 @@ __metadata: peerDependenciesMeta: "@remix-run/cloudflare": optional: true - "@remix-run/deno": - optional: true "@remix-run/node": optional: true "@remix-run/react": @@ -15722,7 +15595,7 @@ __metadata: optional: true zod: optional: true - checksum: 10/2654ad7e49bc3e9517f05f6cca60a864127748a2e0394323075a84f89a180dee6adb7b68d6c89380b9ed11cf38a2e24b409b1457689f1ed1119b6548f3731a2b + checksum: 10/eba6331e68dc5440222f803f6b70e05068a9141f57f5a733b34d2451f1e14f03199dc4d376e46dc2a71e742ad11c4e3283b856ad09a6ea453ca0ce7506453384 languageName: node linkType: hard @@ -15893,69 +15766,6 @@ __metadata: languageName: node linkType: hard -"rollup@npm:^4.2.0": - version: 4.19.0 - resolution: "rollup@npm:4.19.0" - dependencies: - "@rollup/rollup-android-arm-eabi": "npm:4.19.0" - "@rollup/rollup-android-arm64": "npm:4.19.0" - "@rollup/rollup-darwin-arm64": "npm:4.19.0" - "@rollup/rollup-darwin-x64": "npm:4.19.0" - "@rollup/rollup-linux-arm-gnueabihf": "npm:4.19.0" - "@rollup/rollup-linux-arm-musleabihf": "npm:4.19.0" - "@rollup/rollup-linux-arm64-gnu": "npm:4.19.0" - "@rollup/rollup-linux-arm64-musl": "npm:4.19.0" - "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.19.0" - "@rollup/rollup-linux-riscv64-gnu": "npm:4.19.0" - "@rollup/rollup-linux-s390x-gnu": "npm:4.19.0" - "@rollup/rollup-linux-x64-gnu": "npm:4.19.0" - "@rollup/rollup-linux-x64-musl": "npm:4.19.0" - "@rollup/rollup-win32-arm64-msvc": "npm:4.19.0" - "@rollup/rollup-win32-ia32-msvc": "npm:4.19.0" - "@rollup/rollup-win32-x64-msvc": "npm:4.19.0" - "@types/estree": "npm:1.0.5" - fsevents: "npm:~2.3.2" - dependenciesMeta: - "@rollup/rollup-android-arm-eabi": - optional: true - "@rollup/rollup-android-arm64": - optional: true - "@rollup/rollup-darwin-arm64": - optional: true - "@rollup/rollup-darwin-x64": - optional: true - "@rollup/rollup-linux-arm-gnueabihf": - optional: true - "@rollup/rollup-linux-arm-musleabihf": - optional: true - "@rollup/rollup-linux-arm64-gnu": - optional: true - "@rollup/rollup-linux-arm64-musl": - optional: true - "@rollup/rollup-linux-powerpc64le-gnu": - optional: true - "@rollup/rollup-linux-riscv64-gnu": - optional: true - "@rollup/rollup-linux-s390x-gnu": - optional: true - "@rollup/rollup-linux-x64-gnu": - optional: true - "@rollup/rollup-linux-x64-musl": - optional: true - "@rollup/rollup-win32-arm64-msvc": - optional: true - "@rollup/rollup-win32-ia32-msvc": - optional: true - "@rollup/rollup-win32-x64-msvc": - optional: true - fsevents: - optional: true - bin: - rollup: dist/bin/rollup - checksum: 10/a5f56e60d160e727f372fb0b0adbab03c1e5b858df7af62e626459687e6510d5b9685e4badef50bb6ffd916eaf53c1684a8e12ae959dacb8e6930c77a00a0f19 - languageName: node - linkType: hard - "rollup@npm:^4.20.0": version: 4.21.0 resolution: "rollup@npm:4.21.0" @@ -16101,7 +15911,7 @@ __metadata: languageName: node linkType: hard -"scheduler@npm:^0.23.0, scheduler@npm:^0.23.2": +"scheduler@npm:^0.23.2": version: 0.23.2 resolution: "scheduler@npm:0.23.2" dependencies: @@ -16186,9 +15996,9 @@ __metadata: languageName: node linkType: hard -"send@npm:0.18.0": - version: 0.18.0 - resolution: "send@npm:0.18.0" +"send@npm:0.19.0": + version: 0.19.0 + resolution: "send@npm:0.19.0" dependencies: debug: "npm:2.6.9" depd: "npm:2.0.0" @@ -16203,7 +16013,7 @@ __metadata: on-finished: "npm:2.4.1" range-parser: "npm:~1.2.1" statuses: "npm:2.0.1" - checksum: 10/ec66c0ad109680ad8141d507677cfd8b4e40b9559de23191871803ed241718e99026faa46c398dcfb9250676076573bd6bfe5d0ec347f88f4b7b8533d1d391cb + checksum: 10/1f6064dea0ae4cbe4878437aedc9270c33f2a6650a77b56a16b62d057527f2766d96ee282997dd53ec0339082f2aad935bc7d989b46b48c82fc610800dc3a1d0 languageName: node linkType: hard @@ -16227,15 +16037,15 @@ __metadata: languageName: node linkType: hard -"serve-static@npm:1.15.0": - version: 1.15.0 - resolution: "serve-static@npm:1.15.0" +"serve-static@npm:1.16.2": + version: 1.16.2 + resolution: "serve-static@npm:1.16.2" dependencies: - encodeurl: "npm:~1.0.2" + encodeurl: "npm:~2.0.0" escape-html: "npm:~1.0.3" parseurl: "npm:~1.3.3" - send: "npm:0.18.0" - checksum: 10/699b2d4c29807a51d9b5e0f24955346911437aebb0178b3c4833ad30d3eca93385ff9927254f5c16da345903cad39d9cd4a532198c95a5129cc4ed43911b15a4 + send: "npm:0.19.0" + checksum: 10/7fa9d9c68090f6289976b34fc13c50ac8cd7f16ae6bce08d16459300f7fc61fbc2d7ebfa02884c073ec9d6ab9e7e704c89561882bbe338e99fcacb2912fde737 languageName: node linkType: hard @@ -16265,6 +16075,20 @@ __metadata: languageName: node linkType: hard +"set-function-length@npm:^1.2.1": + version: 1.2.2 + resolution: "set-function-length@npm:1.2.2" + dependencies: + define-data-property: "npm:^1.1.4" + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + get-intrinsic: "npm:^1.2.4" + gopd: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.2" + checksum: 10/505d62b8e088468917ca4e3f8f39d0e29f9a563b97dbebf92f4bd2c3172ccfb3c5b8e4566d5fcd00784a00433900e7cb8fbc404e2dbd8c3818ba05bb9d4a8a6d + languageName: node + linkType: hard + "setimmediate@npm:^1.0.5": version: 1.0.5 resolution: "setimmediate@npm:1.0.5" @@ -16302,14 +16126,15 @@ __metadata: languageName: node linkType: hard -"side-channel@npm:^1.0.4": - version: 1.0.4 - resolution: "side-channel@npm:1.0.4" +"side-channel@npm:^1.0.6": + version: 1.0.6 + resolution: "side-channel@npm:1.0.6" dependencies: - call-bind: "npm:^1.0.0" - get-intrinsic: "npm:^1.0.2" - object-inspect: "npm:^1.9.0" - checksum: 10/c4998d9fc530b0e75a7fd791ad868fdc42846f072734f9080ff55cc8dc7d3899abcda24fd896aa6648c3ab7021b4bb478073eb4f44dfd55bce9714bc1a7c5d45 + call-bind: "npm:^1.0.7" + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.4" + object-inspect: "npm:^1.13.1" + checksum: 10/eb10944f38cebad8ad643dd02657592fa41273ce15b8bfa928d3291aff2d30c20ff777cfe908f76ccc4551ace2d1245822fdc576657cce40e9066c638ca8fa4d languageName: node linkType: hard @@ -16482,6 +16307,13 @@ __metadata: languageName: node linkType: hard +"source-map-js@npm:^1.2.1": + version: 1.2.1 + resolution: "source-map-js@npm:1.2.1" + checksum: 10/ff9d8c8bf096d534a5b7707e0382ef827b4dd360a577d3f34d2b9f48e12c9d230b5747974ee7c607f0df65113732711bb701fe9ece3c7edbd43cb2294d707df3 + languageName: node + linkType: hard + "source-map-support@npm:^0.5.21, source-map-support@npm:~0.5.20": version: 0.5.21 resolution: "source-map-support@npm:0.5.21" @@ -16865,10 +16697,10 @@ __metadata: languageName: node linkType: hard -"tailwind-merge@npm:2.4.0": - version: 2.4.0 - resolution: "tailwind-merge@npm:2.4.0" - checksum: 10/dda331a95146c9943dd18f152156fe7a5daf450a686d0562fb521ebc027273bd0c8f9503742668b3e90d27e887aa794ea5e79c38faa51216e19e9d0f1ec55925 +"tailwind-merge@npm:2.5.4": + version: 2.5.4 + resolution: "tailwind-merge@npm:2.5.4" + checksum: 10/2bf6585a30c0ab2e4e8c4bfe0d0a14edbf8e1d88bb8ce68c79f7185e8a7e410893903a98f5819cf8843f1afbe87639e1989af28456cbb0240ddec3468f303727 languageName: node linkType: hard @@ -16921,9 +16753,9 @@ __metadata: languageName: node linkType: hard -"tailwindcss@npm:3.4.4": - version: 3.4.4 - resolution: "tailwindcss@npm:3.4.4" +"tailwindcss@npm:3.4.14": + version: 3.4.14 + resolution: "tailwindcss@npm:3.4.14" dependencies: "@alloc/quick-lru": "npm:^5.2.0" arg: "npm:^5.0.2" @@ -16950,7 +16782,7 @@ __metadata: bin: tailwind: lib/cli.js tailwindcss: lib/cli.js - checksum: 10/ab120014a68517c079fbeecba06c404ac94088a959b5b5e631214af4d87b332b6e4b28d8453f65eac9d94759a030ca581b1330f7d73cbf497883c4e2de083432 + checksum: 10/2b75b697d4859ce813947b043edf19ed61f80321914743a00ba883f327016e4f7f9414823b6ccffeb1359524335c47933d970da5ce2158329f43e9a89d934eb0 languageName: node linkType: hard @@ -17023,8 +16855,8 @@ __metadata: linkType: hard "terser@npm:^5.26.0": - version: 5.31.3 - resolution: "terser@npm:5.31.3" + version: 5.36.0 + resolution: "terser@npm:5.36.0" dependencies: "@jridgewell/source-map": "npm:^0.3.3" acorn: "npm:^8.8.2" @@ -17032,7 +16864,7 @@ __metadata: source-map-support: "npm:~0.5.20" bin: terser: bin/terser - checksum: 10/7f66d93a1157f66f5eda16515ed45e6eb485d3c4acbc46e78a5e62922f5b4643d9212abc586f791021fafc71563a93475a986c52f4270a5e0b3ee50a70507d9e + checksum: 10/52e641419f79d7ccdecd136b9a8e0b03f93cfe3b53cce556253aaabc347d3f2af1745419b9e622abc95d592084dc76e57774b8f9e68d29d543f4dd11c044daf4 languageName: node linkType: hard @@ -17187,17 +17019,10 @@ __metadata: languageName: node linkType: hard -"ts-pattern@npm:5.2.0": - version: 5.2.0 - resolution: "ts-pattern@npm:5.2.0" - checksum: 10/d85607629a46d93a6245b3b17238648fda49d3ab01366df4d049dd5b293876de599f0a810c9a62de13adad38028ffb336539f612bc2686a1f879cd1f3f671a0c - languageName: node - linkType: hard - -"ts-pattern@npm:5.3.1": - version: 5.3.1 - resolution: "ts-pattern@npm:5.3.1" - checksum: 10/e20be66468abb92617d909146737c7d96a4eda55c0e6ef38fece2a266a6242805daabe98adc57c6081593a11cb970b0f026fee086e337c20d145962465c74e4c +"ts-pattern@npm:5.5.0": + version: 5.5.0 + resolution: "ts-pattern@npm:5.5.0" + checksum: 10/d07b22cc65ea4601be588f9ac6e9aeafdc36e13bb3779bcb2ca298e9010b14eca34305c61ad89c0c68e52c5ea5725584fab5e500f5efdf5922289b36b398b684 languageName: node linkType: hard @@ -17208,20 +17033,6 @@ __metadata: languageName: node linkType: hard -"tsconfck@npm:^2.1.0": - version: 2.1.2 - resolution: "tsconfck@npm:2.1.2" - peerDependencies: - typescript: ^4.3.5 || ^5.0.0 - peerDependenciesMeta: - typescript: - optional: true - bin: - tsconfck: bin/tsconfck.js - checksum: 10/61df3b03b334a25eabb0a52e67a0c8d85770c631f2739db7703af8fdd102a2ebd598f1c851cc5fc6d6a59f2497a26c845be71c934ea16d838a3ff95a885034fb - languageName: node - linkType: hard - "tsconfck@npm:^3.0.3": version: 3.0.3 resolution: "tsconfck@npm:3.0.3" @@ -17268,17 +17079,10 @@ __metadata: languageName: node linkType: hard -"turbo-stream@npm:2.2.0": - version: 2.2.0 - resolution: "turbo-stream@npm:2.2.0" - checksum: 10/1a61be95585d6c901c7f626497765e28c38332f6562f4206e8a295dca87297d044f2413f369764365a6cbb13aae3c21fee2aace4525ff32c1e787e418916914e - languageName: node - linkType: hard - -"turbo-stream@npm:2.3.0": - version: 2.3.0 - resolution: "turbo-stream@npm:2.3.0" - checksum: 10/68fd6d4b39a865a82e484563f4134c061b25c784ef80f4d8a8f909074a37162bd9b4466b5bd6b929ea9261fca09b7481d1a50b282383458d928c8bdbf5be7d18 +"tslib@npm:^2.6.3": + version: 2.8.0 + resolution: "tslib@npm:2.8.0" + checksum: 10/1bc7c43937477059b4d26f2dbde7e49ef0fb4f38f3014e0603eaea76d6a885742c8b1762af45949145e5e7408a736d20ded949da99dabc8ccba1fc5531d2d927 languageName: node linkType: hard @@ -17331,6 +17135,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^4.18.1": + version: 4.26.1 + resolution: "type-fest@npm:4.26.1" + checksum: 10/b82676194f80af228cb852e320d2ea8381c89d667d2e4d9f2bdfc8f254bccc039c7741a90c53617a4de0c9fdca8265ed18eb0888cd628f391c5c381c33a9f94b + languageName: node + linkType: hard + "type-fest@npm:^4.3.1": version: 4.19.0 resolution: "type-fest@npm:4.19.0" @@ -17338,13 +17149,6 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^4.3.3": - version: 4.7.0 - resolution: "type-fest@npm:4.7.0" - checksum: 10/eebb9297b3f4a929db98ef56d459e1ca1cccac5cb53696fb2d6264b33a3df9857727fa7951796b29092d9d271ad7fc033970b23e3275ed26a61647988fe91fb4 - languageName: node - linkType: hard - "type-is@npm:~1.6.18": version: 1.6.18 resolution: "type-is@npm:1.6.18" @@ -17409,13 +17213,13 @@ __metadata: languageName: node linkType: hard -"typescript@npm:5.5.4": - version: 5.5.4 - resolution: "typescript@npm:5.5.4" +"typescript@npm:5.6.3": + version: 5.6.3 + resolution: "typescript@npm:5.6.3" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/1689ccafef894825481fc3d856b4834ba3cc185a9c2878f3c76a9a1ef81af04194849840f3c69e7961e2312771471bb3b460ca92561e1d87599b26c37d0ffb6f + checksum: 10/c328e418e124b500908781d9f7b9b93cf08b66bf5936d94332b463822eea2f4e62973bfb3b8a745fdc038785cb66cf59d1092bac3ec2ac6a3e5854687f7833f1 languageName: node linkType: hard @@ -17439,13 +17243,13 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@npm%3A5.5.4#optional!builtin": - version: 5.5.4 - resolution: "typescript@patch:typescript@npm%3A5.5.4#optional!builtin::version=5.5.4&hash=5adc0c" +"typescript@patch:typescript@npm%3A5.6.3#optional!builtin": + version: 5.6.3 + resolution: "typescript@patch:typescript@npm%3A5.6.3#optional!builtin::version=5.6.3&hash=5adc0c" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/2c065f0ef81855eac25c9b658a3c9da65ffc005260c12854c2286f40f3667e1b1ecf8bdbdd37b59aa0397920378ce7900bff8cb32e0f1c7af6fd86efc676718c + checksum: 10/dc4bec403cd33a204b655b1152a096a08e7bad2c931cb59ef8ff26b6f2aa541bf98f09fc157958a60c921b1983a8dde9a85b692f9de60fa8f574fd131e3ae4dd languageName: node linkType: hard @@ -17691,6 +17495,20 @@ __metadata: languageName: node linkType: hard +"update-browserslist-db@npm:^1.1.1": + version: 1.1.1 + resolution: "update-browserslist-db@npm:1.1.1" + dependencies: + escalade: "npm:^3.2.0" + picocolors: "npm:^1.1.0" + peerDependencies: + browserslist: ">= 4.21.0" + bin: + update-browserslist-db: cli.js + checksum: 10/7678dd8609750588d01aa7460e8eddf2ff9d16c2a52fb1811190e0d056390f1fdffd94db3cf8fb209cf634ab4fa9407886338711c71cc6ccade5eeb22b093734 + languageName: node + linkType: hard + "upper-case-first@npm:^2.0.2": version: 2.0.2 resolution: "upper-case-first@npm:2.0.2" @@ -17718,12 +17536,10 @@ __metadata: languageName: node linkType: hard -"urlpattern-polyfill@npm:^7.0.0": - version: 7.0.0 - resolution: "urlpattern-polyfill@npm:7.0.0" - dependencies: - braces: "npm:^3.0.2" - checksum: 10/fdcf1fa889a32f68e9a0144e78e8f4887f54ab0b6dba2be507a2342b192530f08d225e031df6fe64a630e0989eb277def0bf58e01d9eb44e9a10c89bfa5a8696 +"urlpattern-polyfill@npm:^10.0.0": + version: 10.0.0 + resolution: "urlpattern-polyfill@npm:10.0.0" + checksum: 10/346819dbe718e929988298d02a988b8ddfa601d08daaa7e69b1148eab699c86c0f0f933d68d8c8cf913166fe64156ed28904e673200d18ef7e9ed6b58cea3fc7 languageName: node linkType: hard @@ -17865,12 +17681,12 @@ __metadata: languageName: node linkType: hard -"uuid@npm:^9.0.1": - version: 9.0.1 - resolution: "uuid@npm:9.0.1" +"uuid@npm:^8.3.1": + version: 8.3.2 + resolution: "uuid@npm:8.3.2" bin: uuid: dist/bin/uuid - checksum: 10/9d0b6adb72b736e36f2b1b53da0d559125ba3e39d913b6072f6f033e0c87835b414f0836b45bcfaf2bdf698f92297fea1c3cc19b0b258bc182c9c43cc0fab9f2 + checksum: 10/9a5f7aa1d6f56dd1e8d5f2478f855f25c645e64e26e347a98e98d95781d5ed20062d6cca2eecb58ba7c84bc3910be95c0451ef4161906abaab44f9cb68ffbdd1 languageName: node linkType: hard @@ -17983,22 +17799,6 @@ __metadata: languageName: node linkType: hard -"vite-tsconfig-paths@npm:4.2.1": - version: 4.2.1 - resolution: "vite-tsconfig-paths@npm:4.2.1" - dependencies: - debug: "npm:^4.1.1" - globrex: "npm:^0.1.2" - tsconfck: "npm:^2.1.0" - peerDependencies: - vite: "*" - peerDependenciesMeta: - vite: - optional: true - checksum: 10/fd21e99a9bcd4ddb995727a9cf7b87ca95308b0b67e69bee2b836024aabe962b2206fbb62e66645638a1298fd171f8a2b0b55202da7cc801a31b3efa41a3fb2f - languageName: node - linkType: hard - "vite-tsconfig-paths@npm:5.0.1": version: 5.0.1 resolution: "vite-tsconfig-paths@npm:5.0.1" @@ -18015,53 +17815,13 @@ __metadata: languageName: node linkType: hard -"vite@npm:5.1.0": - version: 5.1.0 - resolution: "vite@npm:5.1.0" - dependencies: - esbuild: "npm:^0.19.3" - fsevents: "npm:~2.3.3" - postcss: "npm:^8.4.35" - rollup: "npm:^4.2.0" - peerDependencies: - "@types/node": ^18.0.0 || >=20.0.0 - less: "*" - lightningcss: ^1.21.0 - sass: "*" - stylus: "*" - sugarss: "*" - terser: ^5.4.0 - dependenciesMeta: - fsevents: - optional: true - peerDependenciesMeta: - "@types/node": - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - bin: - vite: bin/vite.js - checksum: 10/14d136f2e71d657cb55bec2a9330951e27e572ed79c4e79e3edc24decfa87f95664b8206614bfcf6a61db933667e554a8eed389291ad8af49de0784548a83a4c - languageName: node - linkType: hard - -"vite@npm:5.4.2": - version: 5.4.2 - resolution: "vite@npm:5.4.2" +"vite@npm:5.4.9": + version: 5.4.9 + resolution: "vite@npm:5.4.9" dependencies: esbuild: "npm:^0.21.3" fsevents: "npm:~2.3.3" - postcss: "npm:^8.4.41" + postcss: "npm:^8.4.43" rollup: "npm:^4.20.0" peerDependencies: "@types/node": ^18.0.0 || >=20.0.0 @@ -18094,7 +17854,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10/c449f9295060fa88c9b5cc1bd17c2de198deae596b7da1250db9662fb15e7b21e0dbe9a40a9106fb7438b1231494b169457e809ecbb65e732648d87dd284ab23 + checksum: 10/60dfb3912ba6367d2d128e798d899caae3f4ec58990657b9f679c4d9de21ddec7eba5f6ad3d4fa0e8ea31771d477521b8e757a622ecc54829d73cb7f7c146bc4 languageName: node linkType: hard @@ -18138,13 +17898,22 @@ __metadata: languageName: node linkType: hard +"warning@npm:^3.0.0": + version: 3.0.0 + resolution: "warning@npm:3.0.0" + dependencies: + loose-envify: "npm:^1.0.0" + checksum: 10/c9f99a12803aab81b29858e7dc3415bf98b41baee3a4c3acdeb680d98c47b6e17490f1087dccc54432deed5711a5ce0ebcda2b27e9b5eb054c32ae50acb4419c + languageName: node + linkType: hard + "watchpack@npm:^2.4.1": - version: 2.4.1 - resolution: "watchpack@npm:2.4.1" + version: 2.4.2 + resolution: "watchpack@npm:2.4.2" dependencies: glob-to-regexp: "npm:^0.4.1" graceful-fs: "npm:^4.1.2" - checksum: 10/0736ebd20b75d3931f9b6175c819a66dee29297c1b389b2e178bc53396a6f867ecc2fd5d87a713ae92dcb73e487daec4905beee20ca00a9e27f1184a7c2bca5e + checksum: 10/6bd4c051d9af189a6c781c3158dcb3069f432a0c144159eeb0a44117412105c61b2b683a5c9eebc4324625e0e9b76536387d0ba354594fa6cbbdf1ef60bee4c3 languageName: node linkType: hard @@ -18170,26 +17939,13 @@ __metadata: languageName: node linkType: hard -"web-streams-polyfill@npm:^3.1.1, web-streams-polyfill@npm:^3.2.1": +"web-streams-polyfill@npm:^3.1.1": version: 3.2.1 resolution: "web-streams-polyfill@npm:3.2.1" checksum: 10/08fcf97b7883c1511dd3da794f50e9bde75a660884783baaddb2163643c21a94086f394dc4bd20dff0f55c98d98d60c4bea05a5809ef5005bdf835b63ada8900 languageName: node linkType: hard -"webcrypto-core@npm:^1.7.7": - version: 1.7.7 - resolution: "webcrypto-core@npm:1.7.7" - dependencies: - "@peculiar/asn1-schema": "npm:^2.3.6" - "@peculiar/json-schema": "npm:^1.1.12" - asn1js: "npm:^3.0.1" - pvtsutils: "npm:^1.3.2" - tslib: "npm:^2.4.0" - checksum: 10/e87ac59d7d05c2aa96117c8f589e99ec9556dfc9ff3cd7fe9464de32e60ed6ff237cdfd35ed53c93546dd0d548bab67b244be381e97b162fe87b6d826e8765ae - languageName: node - linkType: hard - "webidl-conversions@npm:^3.0.0": version: 3.0.1 resolution: "webidl-conversions@npm:3.0.1" @@ -18205,10 +17961,9 @@ __metadata: linkType: hard "webpack@npm:^5": - version: 5.93.0 - resolution: "webpack@npm:5.93.0" + version: 5.95.0 + resolution: "webpack@npm:5.95.0" dependencies: - "@types/eslint-scope": "npm:^3.7.3" "@types/estree": "npm:^1.0.5" "@webassemblyjs/ast": "npm:^1.12.1" "@webassemblyjs/wasm-edit": "npm:^1.12.1" @@ -18217,7 +17972,7 @@ __metadata: acorn-import-attributes: "npm:^1.9.5" browserslist: "npm:^4.21.10" chrome-trace-event: "npm:^1.0.2" - enhanced-resolve: "npm:^5.17.0" + enhanced-resolve: "npm:^5.17.1" es-module-lexer: "npm:^1.2.1" eslint-scope: "npm:5.1.1" events: "npm:^3.2.0" @@ -18237,7 +17992,7 @@ __metadata: optional: true bin: webpack: bin/webpack.js - checksum: 10/a48bef7a511d826db7f9ebee2c84317214923ac40cb2aabe6a649546c54a76a55fc3b91ff03c05fed22a13a176891c47bbff7fcc644c53bcbe5091555863641b + checksum: 10/0377ad3a550b041f26237c96fb55754625b0ce6bae83c1c2447e3262ad056b0b0ad770dcbb92b59f188e9a2bd56155ce910add17dcf023cfbe78bdec774380c1 languageName: node linkType: hard @@ -18357,9 +18112,9 @@ __metadata: languageName: node linkType: hard -"ws@npm:^7.4.5": - version: 7.5.9 - resolution: "ws@npm:7.5.9" +"ws@npm:^7.5.10": + version: 7.5.10 + resolution: "ws@npm:7.5.10" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ^5.0.2 @@ -18368,7 +18123,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 10/171e35012934bd8788150a7f46f963e50bac43a4dc524ee714c20f258693ac4d3ba2abadb00838fdac42a47af9e958c7ae7e6f4bc56db047ba897b8a2268cf7c + checksum: 10/9c796b84ba80ffc2c2adcdfc9c8e9a219ba99caa435c9a8d45f9ac593bba325563b3f83edc5eb067cc6d21b9a6bf2c930adf76dd40af5f58a5ca6859e81858f0 languageName: node linkType: hard @@ -18522,7 +18277,7 @@ __metadata: languageName: node linkType: hard -"zod@npm:3.23.8, zod@npm:^3.17.3, zod@npm:^3.22.4, zod@npm:^3.23.5, zod@npm:^3.23.8": +"zod@npm:3.23.8, zod@npm:^3.17.3, zod@npm:^3.23.5, zod@npm:^3.23.8": version: 3.23.8 resolution: "zod@npm:3.23.8" checksum: 10/846fd73e1af0def79c19d510ea9e4a795544a67d5b34b7e1c4d0425bf6bfd1c719446d94cdfa1721c1987d891321d61f779e8236fde517dc0e524aa851a6eff1