From 8633ac4bcecb7639bf7fbb6437ad77ba65184c81 Mon Sep 17 00:00:00 2001 From: k4rli Date: Thu, 24 Jul 2025 07:59:17 +0300 Subject: [PATCH 01/12] feat(MED-48): add synlab analysis package email --- .../src/components/common-footer.tsx | 22 +++++ .../email-templates/src/components/footer.tsx | 2 +- .../src/emails/synlab.email.tsx | 97 +++++++++++++++++++ packages/email-templates/src/index.ts | 1 + packages/email-templates/src/lib/i18n.ts | 2 +- .../src/locales/en/common.json | 8 ++ .../src/locales/en/synlab-email.json | 12 +++ .../src/locales/et/common.json | 8 ++ .../src/locales/et/synlab-email.json | 12 +++ 9 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 packages/email-templates/src/components/common-footer.tsx create mode 100644 packages/email-templates/src/emails/synlab.email.tsx create mode 100644 packages/email-templates/src/locales/en/common.json create mode 100644 packages/email-templates/src/locales/en/synlab-email.json create mode 100644 packages/email-templates/src/locales/et/common.json create mode 100644 packages/email-templates/src/locales/et/synlab-email.json diff --git a/packages/email-templates/src/components/common-footer.tsx b/packages/email-templates/src/components/common-footer.tsx new file mode 100644 index 0000000..846ddc4 --- /dev/null +++ b/packages/email-templates/src/components/common-footer.tsx @@ -0,0 +1,22 @@ +import { TFunction } from "i18next"; +import { Text } from "@react-email/components"; +import { EmailFooter } from "./footer"; + +export default function CommonFooter({ t }: { t: TFunction }) { + const namespace = 'common'; + + const lines = [ + t(`${namespace}:footer.lines1`), + t(`${namespace}:footer.lines2`), + t(`${namespace}:footer.lines3`), + t(`${namespace}:footer.lines4`), + ]; + + return ( + + {lines.map((line, index) => ( + + ))} + + ) +} diff --git a/packages/email-templates/src/components/footer.tsx b/packages/email-templates/src/components/footer.tsx index c1223dd..c201795 100644 --- a/packages/email-templates/src/components/footer.tsx +++ b/packages/email-templates/src/components/footer.tsx @@ -2,7 +2,7 @@ import { Container, Text } from '@react-email/components'; export function EmailFooter(props: React.PropsWithChildren) { return ( - + {props.children} diff --git a/packages/email-templates/src/emails/synlab.email.tsx b/packages/email-templates/src/emails/synlab.email.tsx new file mode 100644 index 0000000..2dfcf27 --- /dev/null +++ b/packages/email-templates/src/emails/synlab.email.tsx @@ -0,0 +1,97 @@ +import { + Body, + Head, + Html, + Preview, + Tailwind, + Text, + render, +} from '@react-email/components'; + +import { BodyStyle } from '../components/body-style'; +import { EmailContent } from '../components/content'; +import { EmailHeader } from '../components/header'; +import { EmailHeading } from '../components/heading'; +import { EmailWrapper } from '../components/wrapper'; +import { initializeEmailI18n } from '../lib/i18n'; +import CommonFooter from '../components/common-footer'; + +interface Props { + analysisPackageName: string; + language?: string; + personName: string; + partnerLocationName: string; +} + +export async function renderSynlabAnalysisPackageEmail(props: Props) { + const namespace = 'synlab-email'; + + const { t } = await initializeEmailI18n({ + language: props.language, + namespace: [namespace, 'common'], + }); + + const previewText = t(`${namespace}:previewText`); + const subject = t(`${namespace}:subject`); + + const heading = t(`${namespace}:heading`, { + analysisPackageName: props.analysisPackageName, + }); + + const hello = t(`${namespace}:hello`, { + personName: props.personName, + }); + + const lines = [ + t(`${namespace}:lines1`, { + analysisPackageName: props.analysisPackageName, + partnerLocationName: props.partnerLocationName, + }), + t(`${namespace}:lines2`), + t(`${namespace}:lines3`), + t(`${namespace}:lines4`), + t(`${namespace}:lines5`), + t(`${namespace}:lines6`), + ]; + + const html = await render( + + + + + + {previewText} + + + + + + {heading} + + + + + {hello} + + + {lines.map((line, index) => ( + + ))} + + + + + + + , + ); + + return { + html, + subject, + }; +} diff --git a/packages/email-templates/src/index.ts b/packages/email-templates/src/index.ts index 80e5f8a..f9fe5c0 100644 --- a/packages/email-templates/src/index.ts +++ b/packages/email-templates/src/index.ts @@ -2,3 +2,4 @@ export * from './emails/invite.email'; export * from './emails/account-delete.email'; export * from './emails/otp.email'; export * from './emails/company-offer.email'; +export * from './emails/synlab.email'; diff --git a/packages/email-templates/src/lib/i18n.ts b/packages/email-templates/src/lib/i18n.ts index 6c05019..ab47029 100644 --- a/packages/email-templates/src/lib/i18n.ts +++ b/packages/email-templates/src/lib/i18n.ts @@ -2,7 +2,7 @@ import { initializeServerI18n } from '@kit/i18n/server'; export function initializeEmailI18n(params: { language: string | undefined; - namespace: string; + namespace: string | string[]; }) { const language = params.language ?? 'en'; diff --git a/packages/email-templates/src/locales/en/common.json b/packages/email-templates/src/locales/en/common.json new file mode 100644 index 0000000..4474694 --- /dev/null +++ b/packages/email-templates/src/locales/en/common.json @@ -0,0 +1,8 @@ +{ + "footer": { + "lines1": "MedReport", + "lines2": "E-mail: info@medreport.ee", + "lines3": "Customer service: +372 5887 1517", + "lines4": "www.medreport.ee" + } +} \ No newline at end of file diff --git a/packages/email-templates/src/locales/en/synlab-email.json b/packages/email-templates/src/locales/en/synlab-email.json new file mode 100644 index 0000000..61b1d94 --- /dev/null +++ b/packages/email-templates/src/locales/en/synlab-email.json @@ -0,0 +1,12 @@ +{ + "subject": "Your Synlab order has been placed", + "previewText": "Your Synlab order has been placed", + "heading": "Your Synlab order has been placed", + "hello": "Hello {{personName}},", + "lines1": "The order for {{analysisPackageName}} analysis package has been sent to the lab. Please go to the lab to collect the sample: SYNLAB - {{partnerLocationName}}", + "lines2": "If you are unable to go to the lab to collect the sample, you can go to any other suitable collection point - view locations and opening hours.", + "lines3": "It is recommended to collect the sample in the morning (before 12:00) and not to eat or drink (water can be drunk).", + "lines4": "At the collection point, select the order from the queue: the order from the doctor.", + "lines5": "If you have any questions, please contact us.", + "lines6": "SYNLAB customer service phone: 17123" +} \ No newline at end of file diff --git a/packages/email-templates/src/locales/et/common.json b/packages/email-templates/src/locales/et/common.json new file mode 100644 index 0000000..fc58e08 --- /dev/null +++ b/packages/email-templates/src/locales/et/common.json @@ -0,0 +1,8 @@ +{ + "footer": { + "lines1": "MedReport", + "lines2": "E-mail: info@medreport.ee", + "lines3": "Klienditugi: +372 5887 1517", + "lines4": "www.medreport.ee" + } +} \ No newline at end of file diff --git a/packages/email-templates/src/locales/et/synlab-email.json b/packages/email-templates/src/locales/et/synlab-email.json new file mode 100644 index 0000000..2a9147e --- /dev/null +++ b/packages/email-templates/src/locales/et/synlab-email.json @@ -0,0 +1,12 @@ +{ + "subject": "Teie SYNLAB tellimus on kinnitatud", + "previewText": "Teie SYNLAB tellimus on kinnitatud - {{analysisPackageName}}", + "heading": "Teie SYNLAB tellimus on kinnitatud - {{analysisPackageName}}", + "hello": "Tere {{personName}},", + "lines1": "Saatekiri {{analysisPackageName}} analüüsi uuringuteks on saadetud laborisse digitaalselt. Palun mine proove andma: SYNLAB - {{partnerLocationName}}", + "lines2": "Kui Teil ei ole võimalik valitud asukohta minna proove andma, siis võite minna endale sobivasse proovivõtupunkti - vaata asukohti ja lahtiolekuaegasid.", + "lines3": "Soovituslik on proove anda pigem hommikul (enne 12:00) ning söömata ja joomata (vett võib juua).", + "lines4": "Proovivõtupunktis valige järjekorrasüsteemis: saatekirjad alt eriarsti saatekiri.", + "lines5": "Juhul kui tekkis lisaküsimusi, siis võtke julgelt ühendust.", + "lines6": "SYNLAB klienditoe telefon: 17123" +} \ No newline at end of file From e59ad6af005f1aa907c7625691c703c927871bca Mon Sep 17 00:00:00 2001 From: k4rli Date: Thu, 24 Jul 2025 08:02:13 +0300 Subject: [PATCH 02/12] feat(MED-100): update montonio redirect --- app/api/montonio/verify-token/route.ts | 6 - .../montonio-callback/[montonioId]/page.tsx | 23 ---- .../montonio-callback/[montonioId]/route.ts | 113 ++++++++++++++++++ .../cart/montonio-callback/error/page.tsx | 47 ++++++++ app/home/(user)/_components/cart/index.tsx | 22 ++-- .../cart/montonio-checkout-callback.tsx | 101 ---------------- app/home/(user)/_components/cart/types.ts | 22 ++++ lib/services/medusaCart.service.ts | 44 ++++--- .../montonio-order-handler.service.ts | 11 +- .../medusa-storefront/src/lib/data/cart.ts | 17 ++- .../src/lib/data/products.ts | 21 ++++ 11 files changed, 261 insertions(+), 166 deletions(-) delete mode 100644 app/home/(user)/(dashboard)/cart/montonio-callback/[montonioId]/page.tsx create mode 100644 app/home/(user)/(dashboard)/cart/montonio-callback/[montonioId]/route.ts create mode 100644 app/home/(user)/(dashboard)/cart/montonio-callback/error/page.tsx delete mode 100644 app/home/(user)/_components/cart/montonio-checkout-callback.tsx create mode 100644 app/home/(user)/_components/cart/types.ts diff --git a/app/api/montonio/verify-token/route.ts b/app/api/montonio/verify-token/route.ts index 36f305f..6898ac6 100644 --- a/app/api/montonio/verify-token/route.ts +++ b/app/api/montonio/verify-token/route.ts @@ -58,12 +58,6 @@ export const POST = enhanceRouteHandler( algorithms: ['HS256'], }) as MontonioOrderToken; - const activeCartId = request.cookies.get('_medusa_cart_id')?.value; - const [, cartId] = decoded.merchantReferenceDisplay.split(':'); - if (cartId !== activeCartId) { - throw new Error('Invalid cart id'); - } - logger.info( { name: namespace, diff --git a/app/home/(user)/(dashboard)/cart/montonio-callback/[montonioId]/page.tsx b/app/home/(user)/(dashboard)/cart/montonio-callback/[montonioId]/page.tsx deleted file mode 100644 index 1c42dcb..0000000 --- a/app/home/(user)/(dashboard)/cart/montonio-callback/[montonioId]/page.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { PageBody, PageHeader } from '@/packages/ui/src/makerkit/page'; -import { MontonioCheckoutCallback } from '../../../../_components/cart/montonio-checkout-callback'; -import { createI18nServerInstance } from '@/lib/i18n/i18n.server'; -import { Trans } from '@kit/ui/trans'; - -export async function generateMetadata() { - const { t } = await createI18nServerInstance(); - - return { - title: t('cart:montonioCallback.title'), - }; -} - -export default async function MontonioCheckoutCallbackPage() { - return ( -
- } /> - - - -
- ); -} diff --git a/app/home/(user)/(dashboard)/cart/montonio-callback/[montonioId]/route.ts b/app/home/(user)/(dashboard)/cart/montonio-callback/[montonioId]/route.ts new file mode 100644 index 0000000..a295b65 --- /dev/null +++ b/app/home/(user)/(dashboard)/cart/montonio-callback/[montonioId]/route.ts @@ -0,0 +1,113 @@ +import { MontonioOrderToken } from "@/app/home/(user)/_components/cart/types"; +import { loadCurrentUserAccount } from "@/app/home/(user)/_lib/server/load-user-account"; +import { placeOrder } from "@lib/data/cart"; +import jwt from 'jsonwebtoken'; +import { z } from "zod"; +import { createI18nServerInstance } from "~/lib/i18n/i18n.server"; + +const emailSender = process.env.EMAIL_SENDER; +const siteUrl = process.env.NEXT_PUBLIC_SITE_URL!; + +const env = z + .object({ + emailSender: z + .string({ + required_error: 'EMAIL_SENDER is required', + }) + .min(1), + siteUrl: z + .string({ + required_error: 'NEXT_PUBLIC_SITE_URL is required', + }) + .min(1), + }) + .parse({ + emailSender, + siteUrl, + }); + +const sendEmail = async ({ email, analysisPackageName, personName, partnerLocationName, language }: { email: string, analysisPackageName: string, personName: string, partnerLocationName: string, language: string }) => { + try { + const { renderSynlabAnalysisPackageEmail } = await import('@kit/email-templates'); + const { getMailer } = await import('@kit/mailers'); + + const mailer = await getMailer(); + + const { html, subject } = await renderSynlabAnalysisPackageEmail({ + analysisPackageName, + personName, + partnerLocationName, + language, + }); + + await mailer + .sendEmail({ + from: env.emailSender, + to: email, + subject, + html, + }) + .catch((error) => { + throw new Error(`Failed to send email, message=${error}`); + }); + } catch (error) { + throw new Error(`Failed to send email, message=${error}`); + } +} + +const handleOrderToken = async (orderToken: string) => { + const secretKey = process.env.MONTONIO_SECRET_KEY as string; + + const decoded = jwt.verify(orderToken, secretKey, { + algorithms: ['HS256'], + }) as MontonioOrderToken; + if (decoded.paymentStatus !== 'PAID') { + return null; + } + + try { + const [, , cartId] = decoded.merchantReferenceDisplay.split(':'); + if (!cartId) { + throw new Error("Cart ID not found"); + } + const { order } = await placeOrder(cartId, { revalidateCacheTags: true }); + return { + email: order.email, + partnerLocationName: order.metadata?.partner_location_name as string ?? '', + analysisPackageName: order.items?.[0]?.title ?? '', + }; + } catch (error) { + throw new Error(`Failed to place order, message=${error}`); + } +} + +export async function GET(request: Request) { + const { language } = await createI18nServerInstance(); + const baseUrl = new URL(env.siteUrl.replace("localhost", "webhook.site")); + try { + const orderToken = new URL(request.url).searchParams.get('order-token'); + if (!orderToken) { + throw new Error("Order token is missing"); + } + + const account = await loadCurrentUserAccount(); + if (!account) { + throw new Error("Account not found in context"); + } + + const orderResult = await handleOrderToken(orderToken); + if (!orderResult) { + throw new Error("Order result is missing"); + } + + const { email, partnerLocationName, analysisPackageName } = orderResult; + const personName = account.name; + if (email) { + await sendEmail({ email, analysisPackageName, personName, partnerLocationName, language }); + } + return Response.redirect(new URL('/home/order', baseUrl)) + } catch (error) { + console.error("Failed to place order", error); + return Response.redirect(new URL('/home/cart/montonio-callback/error', baseUrl)); + } +} diff --git a/app/home/(user)/(dashboard)/cart/montonio-callback/error/page.tsx b/app/home/(user)/(dashboard)/cart/montonio-callback/error/page.tsx new file mode 100644 index 0000000..cdb64ff --- /dev/null +++ b/app/home/(user)/(dashboard)/cart/montonio-callback/error/page.tsx @@ -0,0 +1,47 @@ +import Link from 'next/link'; + +import { PageBody, PageHeader } from '@/packages/ui/src/makerkit/page'; +import { createI18nServerInstance } from '@/lib/i18n/i18n.server'; +import { Trans } from '@kit/ui/trans'; +import { Alert, AlertDescription } from '@kit/ui/shadcn/alert'; +import { AlertTitle } from '@kit/ui/shadcn/alert'; +import { Button } from '@kit/ui/button'; + +export async function generateMetadata() { + const { t } = await createI18nServerInstance(); + + return { + title: t('cart:montonioCallback.title'), + }; +} + +export default async function MontonioCheckoutCallbackErrorPage() { + return ( +
+ } /> + +
+ + + + + + +

+ +

+
+
+ +
+ +
+
+
+
+ ); +} diff --git a/app/home/(user)/_components/cart/index.tsx b/app/home/(user)/_components/cart/index.tsx index 90f7c7d..f6a4a95 100644 --- a/app/home/(user)/_components/cart/index.tsx +++ b/app/home/(user)/_components/cart/index.tsx @@ -1,5 +1,7 @@ "use client"; +import { useState } from "react"; +import { Loader2 } from "lucide-react"; import { StoreCart, StoreCartLineItem } from "@medusajs/types" import CartItems from "./cart-items" import { Trans } from '@kit/ui/trans'; @@ -10,7 +12,6 @@ import { CardHeader, } from '@kit/ui/card'; import DiscountCode from "./discount-code"; -import { useRouter } from "next/navigation"; import { initiatePaymentSession } from "@lib/data/cart"; import { formatCurrency } from "@/packages/shared/src/utils"; import { useTranslation } from "react-i18next"; @@ -27,9 +28,10 @@ export default function Cart({ analysisPackages: StoreCartLineItem[]; otherItems: StoreCartLineItem[]; }) { - const router = useRouter(); const { i18n: { language } } = useTranslation(); + const [isInitiatingSession, setIsInitiatingSession] = useState(false); + const items = cart?.items ?? []; if (!cart || items.length === 0) { @@ -49,13 +51,18 @@ export default function Cart({ ); } - async function handlePayment() { + async function initiatePayment() { + setIsInitiatingSession(true); const response = await initiatePaymentSession(cart!, { - provider_id: 'pp_system_default', + provider_id: 'pp_montonio_montonio', }); if (response.payment_collection) { - const url = await handleNavigateToPayment({ language }); - router.push(url); + const { payment_sessions } = response.payment_collection; + const paymentSessionId = payment_sessions![0]!.id; + const url = await handleNavigateToPayment({ language, paymentSessionId }); + window.location.href = url; + } else { + setIsInitiatingSession(false); } } @@ -102,7 +109,8 @@ export default function Cart({
-
diff --git a/app/home/(user)/_components/cart/montonio-checkout-callback.tsx b/app/home/(user)/_components/cart/montonio-checkout-callback.tsx deleted file mode 100644 index d6214c7..0000000 --- a/app/home/(user)/_components/cart/montonio-checkout-callback.tsx +++ /dev/null @@ -1,101 +0,0 @@ -'use client'; - -import { useRouter, useSearchParams } from 'next/navigation'; -import { useEffect, useState } from 'react'; - -import { Alert, AlertDescription, AlertTitle } from '@kit/ui/alert'; -import { Button } from '@kit/ui/button'; -import { Trans } from '@kit/ui/trans'; -import { placeOrder } from "@lib/data/cart" -import Link from 'next/link'; -import GlobalLoader from '../../loading'; - -enum Status { - LOADING = 'LOADING', - ERROR = 'ERROR', -} - -export function MontonioCheckoutCallback() { - const router = useRouter(); - const [status, setStatus] = useState(Status.LOADING); - const [isFinalized, setIsFinalized] = useState(false); - const searchParams = useSearchParams(); - - useEffect(() => { - if (isFinalized) { - return; - } - - const token = searchParams.get('order-token'); - if (!token) { - router.push('/home/cart'); - return; - } - - async function verifyToken() { - setStatus(Status.LOADING); - - try { - const response = await fetch('/api/montonio/verify-token', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ token }), - }); - setIsFinalized(true); - - if (!response.ok) { - const body = await response.json(); - throw new Error(body.error ?? 'Failed to verify payment status.'); - } - - const body = await response.json(); - const paymentStatus = body.status as string; - if (paymentStatus === 'PAID') { - try { - await placeOrder(); - } catch (e) { - console.error("Error placing order", e); - router.push('/home/cart'); - } - } else { - throw new Error('Payment failed or pending'); - } - } catch (e) { - console.error("Error verifying token", e); - setStatus(Status.ERROR); - } - } - - void verifyToken(); - }, [searchParams, isFinalized]); - - if (status === Status.ERROR) { - return ( -
- - - - - - -

- -

-
-
- -
- -
-
- ); - } - - return ; -} diff --git a/app/home/(user)/_components/cart/types.ts b/app/home/(user)/_components/cart/types.ts new file mode 100644 index 0000000..22385ce --- /dev/null +++ b/app/home/(user)/_components/cart/types.ts @@ -0,0 +1,22 @@ +export interface MontonioOrderToken { + uuid: string; + accessKey: string; + merchantReference: string; + merchantReferenceDisplay: string; + paymentStatus: + | 'PAID' + | 'FAILED' + | 'CANCELLED' + | 'PENDING' + | 'EXPIRED' + | 'REFUNDED'; + paymentMethod: string; + grandTotal: number; + currency: string; + senderIban?: string; + senderName?: string; + paymentProviderName?: string; + paymentLinkUuid: string; + iat: number; + exp: number; +} \ No newline at end of file diff --git a/lib/services/medusaCart.service.ts b/lib/services/medusaCart.service.ts index c3a59a6..821076f 100644 --- a/lib/services/medusaCart.service.ts +++ b/lib/services/medusaCart.service.ts @@ -1,13 +1,34 @@ 'use server'; +import { z } from 'zod'; import { loadCurrentUserAccount } from '@/app/home/(user)/_lib/server/load-user-account'; import { getSupabaseServerClient } from '@kit/supabase/server-client'; import { addToCart, deleteLineItem, retrieveCart } from '@lib/data/cart'; import { StoreCartLineItem, StoreProductVariant } from '@medusajs/types'; import { MontonioOrderHandlerService } from '@/packages/billing/montonio/src'; -import { headers } from 'next/headers'; import { requireUserInServerComponent } from '../server/require-user-in-server-component'; +const medusaBackendUrl = process.env.MEDUSA_BACKEND_URL!; +const siteUrl = process.env.NEXT_PUBLIC_SITE_URL!; + +const env = z + .object({ + medusaBackendUrl: z + .string({ + required_error: 'MEDUSA_BACKEND_URL is required', + }) + .min(1), + siteUrl: z + .string({ + required_error: 'NEXT_PUBLIC_SITE_URL is required', + }) + .min(1), + }) + .parse({ + medusaBackendUrl, + siteUrl, + }); + export async function handleAddToCart({ selectedVariant, countryCode, @@ -46,7 +67,7 @@ export async function handleAddToCart({ return cart; } -export async function handleNavigateToPayment({ language }: { language: string }) { +export async function handleNavigateToPayment({ language, paymentSessionId }: { language: string, paymentSessionId: string }) { const supabase = getSupabaseServerClient(); const user = await requireUserInServerComponent(); const account = await loadCurrentUserAccount() @@ -59,21 +80,14 @@ export async function handleNavigateToPayment({ language }: { language: string } throw new Error("No cart found"); } - const headersList = await headers(); - const host = "webhook.site:3000"; - const proto = "http"; - // const host = headersList.get('host'); - // const proto = headersList.get('x-forwarded-proto') ?? 'http'; - const publicUrl = `${proto}://${host}`; - const paymentLink = await new MontonioOrderHandlerService().getMontonioPaymentLink({ - notificationUrl: `${publicUrl}/api/billing/webhook`, - returnUrl: `${publicUrl}/home/cart/montonio-callback`, + notificationUrl: `${env.medusaBackendUrl}/api/billing/webhook`, + returnUrl: `${env.siteUrl}/home/cart/montonio-callback`, amount: cart.total, currency: cart.currency_code.toUpperCase(), description: `Order from Medreport`, locale: language, - merchantReference: `${account.id}:${cart.id}:${Date.now()}`, + merchantReference: `${account.id}:${paymentSessionId}:${cart.id}`, }); const { error } = await supabase @@ -104,12 +118,6 @@ export async function handleLineItemTimeout({ throw new Error('Account not found'); } - if (lineItem.updated_at) { - const updatedAt = new Date(lineItem.updated_at); - const now = new Date(); - const diff = now.getTime() - updatedAt.getTime(); - } - await deleteLineItem(lineItem.id); const { error } = await supabase diff --git a/packages/billing/montonio/src/services/montonio-order-handler.service.ts b/packages/billing/montonio/src/services/montonio-order-handler.service.ts index 03aff3d..1a613f6 100644 --- a/packages/billing/montonio/src/services/montonio-order-handler.service.ts +++ b/packages/billing/montonio/src/services/montonio-order-handler.service.ts @@ -30,7 +30,7 @@ export class MontonioOrderHandlerService { locale: string; merchantReference: string; }) { - const token = jwt.sign({ + const params = { accessKey, description, currency, @@ -38,16 +38,17 @@ export class MontonioOrderHandlerService { locale, // 15 minutes expiresAt: new Date(Date.now() + 15 * 60 * 1000).toISOString(), - notificationUrl, - returnUrl, + notificationUrl: notificationUrl.replace("localhost", "webhook.site"), + returnUrl: returnUrl.replace("localhost", "webhook.site"), askAdditionalInfo: false, merchantReference, type: "one_time", - }, secretKey, { + }; + const token = jwt.sign(params, secretKey, { algorithm: "HS256", expiresIn: "10m", }); - + try { const { data } = await axios.post(`${apiUrl}/api/payment-links`, { data: token }); return data.url; diff --git a/packages/features/medusa-storefront/src/lib/data/cart.ts b/packages/features/medusa-storefront/src/lib/data/cart.ts index d739abf..c981ebd 100644 --- a/packages/features/medusa-storefront/src/lib/data/cart.ts +++ b/packages/features/medusa-storefront/src/lib/data/cart.ts @@ -392,7 +392,7 @@ export async function setAddresses(currentState: unknown, formData: FormData) { * @param cartId - optional - The ID of the cart to place an order for. * @returns The cart object if the order was successful, or null if not. */ -export async function placeOrder(cartId?: string) { +export async function placeOrder(cartId?: string, options: { revalidateCacheTags: boolean } = { revalidateCacheTags: true }) { const id = cartId || (await getCartId()); if (!id) { @@ -406,21 +406,26 @@ export async function placeOrder(cartId?: string) { const cartRes = await sdk.store.cart .complete(id, {}, headers) .then(async (cartRes) => { - const cartCacheTag = await getCacheTag("carts"); - revalidateTag(cartCacheTag); + if (options?.revalidateCacheTags) { + const cartCacheTag = await getCacheTag("carts"); + revalidateTag(cartCacheTag); + } return cartRes; }) .catch(medusaError); if (cartRes?.type === "order") { - const orderCacheTag = await getCacheTag("orders"); - revalidateTag(orderCacheTag); + if (options?.revalidateCacheTags) { + const orderCacheTag = await getCacheTag("orders"); + revalidateTag(orderCacheTag); + } removeCartId(); - redirect(`/home/order/${cartRes?.order.id}/confirmed`); } else { throw new Error("Cart is not an order"); } + + return cartRes; } /** diff --git a/packages/features/medusa-storefront/src/lib/data/products.ts b/packages/features/medusa-storefront/src/lib/data/products.ts index 2ef33ab..d671d2c 100644 --- a/packages/features/medusa-storefront/src/lib/data/products.ts +++ b/packages/features/medusa-storefront/src/lib/data/products.ts @@ -134,3 +134,24 @@ export const listProductsWithSort = async ({ queryParams, } } + +export const listProductTypes = async (): Promise<{ productTypes: HttpTypes.StoreProductType[]; count: number }> => { + const next = { + ...(await getCacheOptions("productTypes")), + }; + + return sdk.client + .fetch<{ product_types: HttpTypes.StoreProductType[]; count: number }>( + "/store/product-types", + { + next, + cache: "force-cache", + query: { + fields: "id,value,metadata", + }, + } + ) + .then(({ product_types, count }) => { + return { productTypes: product_types, count }; + }); +}; From 23f656ccc979aff28db72ebcf05ef2bcd15d3a9f Mon Sep 17 00:00:00 2001 From: k4rli Date: Thu, 24 Jul 2025 08:04:04 +0300 Subject: [PATCH 03/12] feat(MED-100): analysis package products by product type --- .../_lib/server/load-analysis-packages.ts | 20 +++++++++---------- .../src/lib/data/products.ts | 2 +- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/app/home/(user)/_lib/server/load-analysis-packages.ts b/app/home/(user)/_lib/server/load-analysis-packages.ts index 3dc758d..59da4ae 100644 --- a/app/home/(user)/_lib/server/load-analysis-packages.ts +++ b/app/home/(user)/_lib/server/load-analysis-packages.ts @@ -1,6 +1,6 @@ import { cache } from 'react'; -import { listCollections, listProducts, listRegions } from "@lib/data"; +import { listProductTypes, listProducts, listRegions } from "@lib/data"; async function countryCodesLoader() { const countryCodes = await listRegions().then((regions) => @@ -10,26 +10,24 @@ async function countryCodesLoader() { } export const loadCountryCodes = cache(countryCodesLoader); -async function collectionsLoader() { - const { collections } = await listCollections({ - fields: 'id, handle', - }); - return collections ?? []; +async function productTypesLoader() { + const { productTypes } = await listProductTypes(); + return productTypes ?? []; } -export const loadCollections = cache(collectionsLoader); +export const loadProductTypes = cache(productTypesLoader); async function analysisPackagesLoader() { - const [countryCodes, collections] = await Promise.all([loadCountryCodes(), loadCollections()]); + const [countryCodes, productTypes] = await Promise.all([loadCountryCodes(), loadProductTypes()]); const countryCode = countryCodes[0]!; - const collection = collections.find(({ handle }) => handle === 'analysis-packages'); - if (!collection) { + const productType = productTypes.find(({ metadata }) => metadata?.handle === 'analysis-packages'); + if (!productType) { return { analysisPackages: [], countryCode }; } const { response } = await listProducts({ countryCode, - queryParams: { limit: 100, collection_id: collection?.id }, + queryParams: { limit: 100, "type_id[0]": productType.id }, }); return { analysisPackages: response.products, countryCode }; } diff --git a/packages/features/medusa-storefront/src/lib/data/products.ts b/packages/features/medusa-storefront/src/lib/data/products.ts index d671d2c..810d205 100644 --- a/packages/features/medusa-storefront/src/lib/data/products.ts +++ b/packages/features/medusa-storefront/src/lib/data/products.ts @@ -14,7 +14,7 @@ export const listProducts = async ({ regionId, }: { pageParam?: number - queryParams?: HttpTypes.FindParams & HttpTypes.StoreProductParams & { collection_id?: string } + queryParams?: HttpTypes.FindParams & HttpTypes.StoreProductParams & { "type_id[0]"?: string } countryCode?: string regionId?: string }): Promise<{ From b9f40d6a2da57a0d757265ef23a2fee71ff5dffe Mon Sep 17 00:00:00 2001 From: k4rli Date: Thu, 24 Jul 2025 08:04:25 +0300 Subject: [PATCH 04/12] feat(MED-100): analysis location select in cart --- app/home/(user)/(dashboard)/cart/page.tsx | 15 ++- .../_components/cart/analysis-location.tsx | 99 +++++++++++++++++++ app/home/(user)/_components/cart/index.tsx | 21 +++- public/locales/en/cart.json | 10 ++ public/locales/et/cart.json | 10 ++ 5 files changed, 145 insertions(+), 10 deletions(-) create mode 100644 app/home/(user)/_components/cart/analysis-location.tsx diff --git a/app/home/(user)/(dashboard)/cart/page.tsx b/app/home/(user)/(dashboard)/cart/page.tsx index cdb0918..bac927a 100644 --- a/app/home/(user)/(dashboard)/cart/page.tsx +++ b/app/home/(user)/(dashboard)/cart/page.tsx @@ -5,7 +5,7 @@ import { notFound } from 'next/navigation'; import { retrieveCart } from '~/medusa/lib/data/cart'; import Cart from '../../_components/cart'; -import { listCollections } from '@lib/data'; +import { listProductTypes } from '@lib/data'; import CartTimer from '../../_components/cart/cart-timer'; import { Trans } from '@kit/ui/trans'; @@ -23,15 +23,12 @@ export default async function CartPage() { return notFound(); }); - const { collections } = await listCollections({ - limit: "100", - }); - - const analysisPackagesCollection = collections.find(({ handle }) => handle === 'analysis-packages'); - const analysisPackages = analysisPackagesCollection && cart?.items - ? cart.items.filter((item) => item.product?.collection_id === analysisPackagesCollection.id) + const { productTypes } = await listProductTypes(); + const analysisPackagesType = productTypes.find(({ metadata }) => metadata?.handle === 'analysis-packages'); + const analysisPackages = analysisPackagesType && cart?.items + ? cart.items.filter((item) => item.product?.type_id === analysisPackagesType.id) : []; - const otherItems = cart?.items?.filter((item) => item.product?.collection_id !== analysisPackagesCollection?.id) ?? []; + const otherItems = cart?.items?.filter((item) => item.product?.type_id !== analysisPackagesType?.id) ?? []; const otherItemsSorted = otherItems.sort((a, b) => (a.updated_at ?? "") > (b.updated_at ?? "") ? -1 : 1); const item = otherItemsSorted[0]; diff --git a/app/home/(user)/_components/cart/analysis-location.tsx b/app/home/(user)/_components/cart/analysis-location.tsx new file mode 100644 index 0000000..89da90c --- /dev/null +++ b/app/home/(user)/_components/cart/analysis-location.tsx @@ -0,0 +1,99 @@ +"use client" + +import { toast } from 'sonner'; +import { useForm } from "react-hook-form"; +import { z } from "zod"; +import { updateCart } from "@lib/data/cart" +import { StoreCart } from "@medusajs/types" +import { Form } from "@kit/ui/form"; +import { Trans } from '@kit/ui/trans'; +import { useTranslation } from "react-i18next"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectLabel, + SelectTrigger, + SelectValue, +} from '@kit/ui/select'; + +const AnalysisLocationSchema = z.object({ + locationId: z.string().min(1), +}); + +const MOCK_LOCATIONS: { id: string, name: string }[] = [ + { id: "synlab-tallinn-1", name: "SYNLAB - Tallinn" }, + { id: "synlab-tartu-1", name: "SYNLAB - Tartu" }, + { id: "synlab-parnu-1", name: "SYNLAB - Pärnu" }, +] + +export default function AnalysisLocation({ cart }: { cart: StoreCart }) { + const { t } = useTranslation('cart'); + + const form = useForm>({ + defaultValues: { + locationId: cart.metadata?.partner_location_id as string ?? '', + }, + resolver: zodResolver(AnalysisLocationSchema), + }); + + const onSubmit = async ({ locationId }: z.infer) => { + const promise = updateCart({ + metadata: { + partner_location_name: MOCK_LOCATIONS.find(({ id }) => id === locationId)?.name ?? '', + partner_location_id: locationId, + }, + }); + + toast.promise(promise, { + success: t(`cart:items.analysisLocation.success`), + loading: t(`cart:items.analysisLocation.loading`), + error: t(`cart:items.analysisLocation.error`), + }); + } + + return ( +
+
+ onSubmit(data))} + className="w-full mb-2 flex gap-x-2" + > + +
+ + +

+ +

+ +
+ ) +} diff --git a/app/home/(user)/_components/cart/index.tsx b/app/home/(user)/_components/cart/index.tsx index f6a4a95..fc05d7c 100644 --- a/app/home/(user)/_components/cart/index.tsx +++ b/app/home/(user)/_components/cart/index.tsx @@ -16,6 +16,7 @@ import { initiatePaymentSession } from "@lib/data/cart"; import { formatCurrency } from "@/packages/shared/src/utils"; import { useTranslation } from "react-i18next"; import { handleNavigateToPayment } from "@/lib/services/medusaCart.service"; +import AnalysisLocation from "./analysis-location"; const IS_DISCOUNT_SHOWN = false as boolean; @@ -66,13 +67,16 @@ export default function Cart({ } } + const hasCartItems = Array.isArray(cart.items) && cart.items.length > 0; + const isLocationsShown = analysisPackages.length > 0; + return (
- {Array.isArray(cart.items) && cart.items.length > 0 && ( + {hasCartItems && (

@@ -106,6 +110,21 @@ export default function Cart({ )} + + {isLocationsShown && ( + + +

+ +
+ + + + + + )}
diff --git a/public/locales/en/cart.json b/public/locales/en/cart.json index 8f83aa1..63cb930 100644 --- a/public/locales/en/cart.json +++ b/public/locales/en/cart.json @@ -40,6 +40,11 @@ "success": "Item removed from cart", "loading": "Removing item from cart", "error": "Failed to remove item from cart" + }, + "analysisLocation": { + "success": "Location updated", + "loading": "Updating location", + "error": "Failed to update location" } }, "orderConfirmed": { @@ -57,5 +62,10 @@ "montonioCallback": { "title": "Montonio checkout", "description": "Please wait while we process your payment." + }, + "locations": { + "title": "Location for analysis", + "description": "If you are unable to go to the lab to collect the sample, you can go to any other suitable collection point.", + "locationSelect": "Select location" } } \ No newline at end of file diff --git a/public/locales/et/cart.json b/public/locales/et/cart.json index f5bcc75..d6026b9 100644 --- a/public/locales/et/cart.json +++ b/public/locales/et/cart.json @@ -41,6 +41,11 @@ "success": "Toode eemaldatud ostukorvist", "loading": "Toote eemaldamine ostukorvist", "error": "Toote eemaldamine ostukorvist ebaõnnestus" + }, + "analysisLocation": { + "success": "Asukoht uuendatud", + "loading": "Asukoha uuendamine", + "error": "Asukoha uuendamine ebaõnnestus" } }, "orderConfirmed": { @@ -58,5 +63,10 @@ "montonioCallback": { "title": "Montonio makseprotsess", "description": "Palun oodake, kuni me töötleme sinu makseprotsessi lõpuni." + }, + "locations": { + "title": "Asukoht analüüside andmiseks", + "description": "Kui Teil ei ole võimalik valitud asukohta minna analüüse andma, siis võite minna Teile sobivasse verevõtupunkti.", + "locationSelect": "Vali asukoht" } } \ No newline at end of file From 57e30911e90299dc018b8b1ce585369188b5aa3f Mon Sep 17 00:00:00 2001 From: k4rli Date: Thu, 24 Jul 2025 08:05:34 +0300 Subject: [PATCH 05/12] feat(MED-100): show cart in mobile menu --- app/home/(user)/(dashboard)/layout.tsx | 11 +++++---- .../_components/home-menu-navigation.tsx | 2 +- .../_components/home-mobile-navigation.tsx | 24 ++++++++++++++++--- public/locales/en/common.json | 1 + public/locales/et/common.json | 1 + 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/app/home/(user)/(dashboard)/layout.tsx b/app/home/(user)/(dashboard)/layout.tsx index 5e08ec6..96d81f5 100644 --- a/app/home/(user)/(dashboard)/layout.tsx +++ b/app/home/(user)/(dashboard)/layout.tsx @@ -7,6 +7,8 @@ import { z } from 'zod'; import { UserWorkspaceContextProvider } from '@kit/accounts/components'; import { Page, PageMobileNavigation, PageNavigation } from '@kit/ui/page'; import { SidebarProvider } from '@kit/ui/shadcn-sidebar'; +import { StoreCart } from '@medusajs/types'; +import { retrieveCart } from '@lib/data'; import { AppLogo } from '~/components/app-logo'; import { personalAccountNavigationConfig } from '~/config/personal-account-navigation.config'; @@ -17,7 +19,6 @@ import { HomeMenuNavigation } from '../_components/home-menu-navigation'; import { HomeMobileNavigation } from '../_components/home-mobile-navigation'; import { HomeSidebar } from '../_components/home-sidebar'; import { loadUserWorkspace } from '../_lib/server/load-user-workspace'; -import { retrieveCart } from '@lib/data'; function UserHomeLayout({ children }: React.PropsWithChildren) { const state = use(getLayoutState()); @@ -44,7 +45,7 @@ function SidebarLayout({ children }: React.PropsWithChildren) { - + {children} @@ -66,7 +67,7 @@ function HeaderLayout({ children }: React.PropsWithChildren) { - + @@ -84,14 +85,16 @@ function HeaderLayout({ children }: React.PropsWithChildren) { function MobileNavigation({ workspace, + cart, }: { workspace: Awaited>; + cart: StoreCart | null; }) { return ( <> - + ); } diff --git a/app/home/(user)/_components/home-menu-navigation.tsx b/app/home/(user)/_components/home-menu-navigation.tsx index 761be60..407ebf1 100644 --- a/app/home/(user)/_components/home-menu-navigation.tsx +++ b/app/home/(user)/_components/home-menu-navigation.tsx @@ -46,7 +46,7 @@ export async function HomeMenuNavigation(props: { workspace: UserWorkspace, cart diff --git a/app/home/(user)/_components/home-mobile-navigation.tsx b/app/home/(user)/_components/home-mobile-navigation.tsx index bd3a502..87fd7d5 100644 --- a/app/home/(user)/_components/home-mobile-navigation.tsx +++ b/app/home/(user)/_components/home-mobile-navigation.tsx @@ -2,7 +2,7 @@ import Link from 'next/link'; -import { LogOut, Menu } from 'lucide-react'; +import { LogOut, Menu, ShoppingCart } from 'lucide-react'; import { useSignOut } from '@kit/supabase/hooks/use-sign-out'; import { @@ -16,6 +16,7 @@ import { } from '@kit/ui/dropdown-menu'; import { If } from '@kit/ui/if'; import { Trans } from '@kit/ui/trans'; +import { StoreCart } from '@medusajs/types'; import featuresFlagConfig from '~/config/feature-flags.config'; import { personalAccountNavigationConfig } from '~/config/personal-account-navigation.config'; @@ -24,7 +25,7 @@ import { personalAccountNavigationConfig } from '~/config/personal-account-navig import { HomeAccountSelector } from '../_components/home-account-selector'; import type { UserWorkspace } from '../_lib/server/load-user-workspace'; -export function HomeMobileNavigation(props: { workspace: UserWorkspace }) { +export function HomeMobileNavigation(props: { workspace: UserWorkspace, cart: StoreCart | null }) { const signOut = useSignOut(); const Links = personalAccountNavigationConfig.routes.map((item, index) => { @@ -46,6 +47,10 @@ export function HomeMobileNavigation(props: { workspace: UserWorkspace }) { } }); + + const cartItemsCount = props.cart?.items?.length ?? 0; + const hasCartItems = cartItemsCount > 0; + return ( @@ -69,6 +74,18 @@ export function HomeMobileNavigation(props: { workspace: UserWorkspace }) { + + + } + labelOptions={{ count: cartItemsCount }} + /> + + + + {Links} @@ -83,6 +100,7 @@ function DropdownLink( props: React.PropsWithChildren<{ path: string; label: string; + labelOptions?: Record; Icon: React.ReactNode; }>, ) { @@ -95,7 +113,7 @@ function DropdownLink( {props.Icon} - + diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 280e9f7..ea42f86 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -58,6 +58,7 @@ "back": "Back", "welcome": "Welcome", "shoppingCart": "Shopping cart", + "shoppingCartCount": "Shopping cart ({{count}})", "search": "Search{{end}}", "myActions": "My actions", "healthPackageComparison": { diff --git a/public/locales/et/common.json b/public/locales/et/common.json index 05008e4..d1e5068 100644 --- a/public/locales/et/common.json +++ b/public/locales/et/common.json @@ -58,6 +58,7 @@ "back": "Back", "welcome": "Tere tulemast", "shoppingCart": "Ostukorv", + "shoppingCartCount": "Ostukorv ({{count}})", "search": "Otsi{{end}}", "myActions": "Minu toimingud", "healthPackageComparison": { From 66760adc06fda1e5005bcf14bab054f746911522 Mon Sep 17 00:00:00 2001 From: k4rli Date: Thu, 24 Jul 2025 08:06:33 +0300 Subject: [PATCH 06/12] feat(MED-50): initial analysis package orders table --- app/home/(user)/(dashboard)/order/page.tsx | 49 +++++++++++++++++++ .../(user)/_components/orders/orders-item.tsx | 44 +++++++++++++++++ .../_components/orders/orders-table.tsx | 46 +++++++++++++++++ app/home/(user)/_components/orders/types.ts | 7 +++ config/paths.config.ts | 2 +- lib/i18n/i18n.settings.ts | 1 + public/locales/en/orders.json | 8 +++ public/locales/et/orders.json | 8 +++ 8 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 app/home/(user)/(dashboard)/order/page.tsx create mode 100644 app/home/(user)/_components/orders/orders-item.tsx create mode 100644 app/home/(user)/_components/orders/orders-table.tsx create mode 100644 app/home/(user)/_components/orders/types.ts create mode 100644 public/locales/en/orders.json create mode 100644 public/locales/et/orders.json diff --git a/app/home/(user)/(dashboard)/order/page.tsx b/app/home/(user)/(dashboard)/order/page.tsx new file mode 100644 index 0000000..511e861 --- /dev/null +++ b/app/home/(user)/(dashboard)/order/page.tsx @@ -0,0 +1,49 @@ +import { redirect } from 'next/navigation'; + +import { listOrders } from '~/medusa/lib/data/orders'; +import { createI18nServerInstance } from '@/lib/i18n/i18n.server'; +import { listProductTypes, retrieveCustomer } from '@lib/data'; +import { PageBody } from '@kit/ui/makerkit/page'; +import pathsConfig from '~/config/paths.config'; +import { Trans } from '@kit/ui/trans'; +import { HomeLayoutPageHeader } from '../../_components/home-page-header'; +import OrdersTable from '../../_components/orders/orders-table'; +import { withI18n } from '~/lib/i18n/with-i18n'; + +export async function generateMetadata() { + const { t } = await createI18nServerInstance(); + + return { + title: t('orders:title'), + }; +} + +async function OrdersPage() { + const customer = await retrieveCustomer(); + const orders = await listOrders().catch(() => null); + const { productTypes } = await listProductTypes(); + + if (!customer || !orders || !productTypes) { + redirect(pathsConfig.auth.signIn); + } + + const analysisPackagesType = productTypes.find(({ metadata }) => metadata?.handle === 'analysis-packages'); + const analysisPackageOrders = orders.flatMap(({ id, items, payment_status, fulfillment_status }) => items + ?.filter((item) => item.product_type_id === analysisPackagesType?.id) + .map((item) => ({ item, orderId: id, orderStatus: `${payment_status}/${fulfillment_status}` })) + || []); + + return ( + <> + } + description={} + /> + + + + + ); +} + +export default withI18n(OrdersPage); diff --git a/app/home/(user)/_components/orders/orders-item.tsx b/app/home/(user)/_components/orders/orders-item.tsx new file mode 100644 index 0000000..26e965b --- /dev/null +++ b/app/home/(user)/_components/orders/orders-item.tsx @@ -0,0 +1,44 @@ +import { + TableCell, + TableRow, +} from '@kit/ui/table'; +import { Eye } from "lucide-react"; +import Link from "next/link"; +import { formatDate } from "date-fns"; +import { IAnalysisPackageOrder } from "./types"; + +export default function OrdersItem({ orderItem }: { + orderItem: IAnalysisPackageOrder, +}) { + return ( + + +

+ {orderItem.item.product_title} +

+
+ + + {formatDate(orderItem.item.created_at, 'dd.MM.yyyy HH:mm')} + + + {orderItem.orderStatus && ( + + {orderItem.orderStatus} + + )} + + + + + + + + +
+ ) +} diff --git a/app/home/(user)/_components/orders/orders-table.tsx b/app/home/(user)/_components/orders/orders-table.tsx new file mode 100644 index 0000000..b2e4b1e --- /dev/null +++ b/app/home/(user)/_components/orders/orders-table.tsx @@ -0,0 +1,46 @@ +import { Trans } from '@kit/ui/trans'; +import { + Table, + TableBody, + TableHead, + TableRow, + TableHeader, +} from '@kit/ui/table'; +import OrdersItem from "./orders-item"; +import { IAnalysisPackageOrder } from "./types"; + +const IS_SHOWN_ORDER_STATUS = true as boolean; + +export default function OrdersTable({ orderItems }: { + orderItems: IAnalysisPackageOrder[]; +}) { + if (!orderItems || orderItems.length === 0) { + return null; + } + + return ( + + + + + + + + + + {IS_SHOWN_ORDER_STATUS && ( + + + )} + + + + + + {orderItems + .sort((a, b) => (a.item.created_at ?? "") > (b.item.created_at ?? "") ? -1 : 1) + .map((orderItem) => ())} + +
+ ) +} diff --git a/app/home/(user)/_components/orders/types.ts b/app/home/(user)/_components/orders/types.ts new file mode 100644 index 0000000..2ad04ce --- /dev/null +++ b/app/home/(user)/_components/orders/types.ts @@ -0,0 +1,7 @@ +import { StoreOrderLineItem } from "@medusajs/types"; + +export interface IAnalysisPackageOrder { + item: StoreOrderLineItem; + orderId: string; + orderStatus: string; +} diff --git a/config/paths.config.ts b/config/paths.config.ts index 0a9ff76..ca6222d 100644 --- a/config/paths.config.ts +++ b/config/paths.config.ts @@ -59,8 +59,8 @@ const pathsConfig = PathsSchema.parse({ selectPackage: '/select-package', booking: '/home/booking', orderAnalysisPackage: '/home/order-analysis-package', + myOrders: '/home/order', // these routes are added as placeholders and can be changed when the pages are added - myOrders: '/my-orders', analysisResults: '/home/analysis-results', orderAnalysis: '/order-analysis', orderHealthAnalysis: '/order-health-analysis', diff --git a/lib/i18n/i18n.settings.ts b/lib/i18n/i18n.settings.ts index 77e22fc..97a8893 100644 --- a/lib/i18n/i18n.settings.ts +++ b/lib/i18n/i18n.settings.ts @@ -37,6 +37,7 @@ export const defaultI18nNamespaces = [ 'booking', 'order-analysis-package', 'cart', + 'orders', ]; /** diff --git a/public/locales/en/orders.json b/public/locales/en/orders.json new file mode 100644 index 0000000..f1f1273 --- /dev/null +++ b/public/locales/en/orders.json @@ -0,0 +1,8 @@ +{ + "title": "Orders", + "description": "View your orders", + "table": { + "analysisPackage": "Analysis package", + "createdAt": "Ordered at" + } +} \ No newline at end of file diff --git a/public/locales/et/orders.json b/public/locales/et/orders.json new file mode 100644 index 0000000..aa2f7ff --- /dev/null +++ b/public/locales/et/orders.json @@ -0,0 +1,8 @@ +{ + "title": "Tellimused", + "description": "Vaata oma tellimusi", + "table": { + "analysisPackage": "Analüüsi pakett", + "createdAt": "Tellitud" + } +} \ No newline at end of file From 349e3e3143578c13560c3107c1d315bff703d8bc Mon Sep 17 00:00:00 2001 From: k4rli Date: Thu, 24 Jul 2025 08:38:12 +0300 Subject: [PATCH 07/12] feat(MED-50): use account_params in dashboard --- app/home/(user)/(dashboard)/page.tsx | 2 +- app/home/(user)/_components/dashboard.tsx | 46 ++++++++++++++++--- packages/features/accounts/src/server/api.ts | 8 +++- packages/supabase/src/database.types.ts | 18 ++++---- ...0724082606_account_params_relation_fix.sql | 1 + 5 files changed, 57 insertions(+), 18 deletions(-) create mode 100644 supabase/migrations/20250724082606_account_params_relation_fix.sql diff --git a/app/home/(user)/(dashboard)/page.tsx b/app/home/(user)/(dashboard)/page.tsx index 75b3d20..2f8b287 100644 --- a/app/home/(user)/(dashboard)/page.tsx +++ b/app/home/(user)/(dashboard)/page.tsx @@ -37,7 +37,7 @@ async function UserHomePage() { } /> - + ); diff --git a/app/home/(user)/_components/dashboard.tsx b/app/home/(user)/_components/dashboard.tsx index 0498cdb..e93ce86 100644 --- a/app/home/(user)/_components/dashboard.tsx +++ b/app/home/(user)/_components/dashboard.tsx @@ -15,6 +15,7 @@ import { TrendingUp, User, } from 'lucide-react'; +import Isikukood from 'isikukood'; import { Button } from '@kit/ui/button'; import { @@ -27,29 +28,40 @@ import { } from '@kit/ui/card'; import { Trans } from '@kit/ui/trans'; import { cn } from '@kit/ui/utils'; +import type { AccountWithParams } from '@/packages/features/accounts/src/server/api'; -const dummyCards = [ +const cards = ({ + gender, + age, + height, + weight, +}: { + gender?: string; + age?: number; + height?: number | null; + weight?: number | null; +}) => [ { title: 'dashboard:gender', - description: 'dashboard:male', + description: gender ?? 'dashboard:male', icon: , iconBg: 'bg-success', }, { title: 'dashboard:age', - description: '43', + description: age ? `${age}` : '-', icon: , iconBg: 'bg-success', }, { title: 'dashboard:height', - description: '183', + description: height ? `${height}cm` : '-', icon: , iconBg: 'bg-success', }, { title: 'dashboard:weight', - description: '92kg', + description: weight ? `${weight}kg` : '-', icon: , iconBg: 'bg-warning', }, @@ -128,11 +140,31 @@ const dummyRecommendations = [ }, ]; -export default function Dashboard() { +const getPersonParameters = (personalCode: string) => { + try { + const person = new Isikukood(personalCode); + return { + gender: person.getGender(), + age: person.getAge(), + }; + } catch (error) { + console.error(error); + return null; + } +}; + +export default function Dashboard({ account }: { account: AccountWithParams }) { + const params = getPersonParameters(account.personal_code!); + return ( <>
- {dummyCards.map( + {cards({ + gender: params?.gender, + age: params?.age, + height: account.account_params?.height, + weight: account.account_params?.weight, + }).map( ({ title, description, diff --git a/packages/features/accounts/src/server/api.ts b/packages/features/accounts/src/server/api.ts index 62c25d9..dba85a8 100644 --- a/packages/features/accounts/src/server/api.ts +++ b/packages/features/accounts/src/server/api.ts @@ -4,6 +4,10 @@ import { Database } from '@kit/supabase/database'; import { UserAnalysis } from '../types/accounts'; +export type AccountWithParams = Database['medreport']['Tables']['accounts']['Row'] & { + account_params: Pick | null; +}; + /** * Class representing an API for interacting with user accounts. * @constructor @@ -17,11 +21,11 @@ class AccountsApi { * @description Get the account data for the given ID. * @param id */ - async getAccount(id: string) { + async getAccount(id: string): Promise { const { data, error } = await this.client .schema('medreport') .from('accounts') - .select('*') + .select('*, account_params: account_params (weight, height)') .eq('id', id) .single(); diff --git a/packages/supabase/src/database.types.ts b/packages/supabase/src/database.types.ts index 9a735ee..0e0daf6 100644 --- a/packages/supabase/src/database.types.ts +++ b/packages/supabase/src/database.types.ts @@ -203,7 +203,15 @@ export type Database = { recorded_at?: string weight?: number | null } - Relationships: [] + Relationships: [ + { + foreignKeyName: "account_params_account_id_fkey" + columns: ["account_id"] + isOneToOne: true + referencedRelation: "accounts" + referencedColumns: ["id"] + }, + ] } accounts: { Row: { @@ -297,13 +305,7 @@ export type Database = { user_id?: string } Relationships: [ - { - foreignKeyName: "accounts_memberships_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] - }, + { foreignKeyName: "accounts_memberships_account_id_fkey" columns: ["account_id"] diff --git a/supabase/migrations/20250724082606_account_params_relation_fix.sql b/supabase/migrations/20250724082606_account_params_relation_fix.sql new file mode 100644 index 0000000..2dd76b2 --- /dev/null +++ b/supabase/migrations/20250724082606_account_params_relation_fix.sql @@ -0,0 +1 @@ +alter table "medreport"."account_params" add constraint "account_params_account_id_fkey" FOREIGN KEY (account_id) REFERENCES medreport.accounts(id) ON DELETE CASCADE not valid; From f26085e36211dc3fd56a5445d6ea2ce22beedbdb Mon Sep 17 00:00:00 2001 From: k4rli Date: Thu, 24 Jul 2025 08:38:30 +0300 Subject: [PATCH 08/12] feat(MED-50): add placeholder pages --- .../(dashboard)/order-analysis/page.tsx | 28 +++++++++++++++++++ .../order-health-analysis/page.tsx | 28 +++++++++++++++++++ config/paths.config.ts | 5 ++-- 3 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 app/home/(user)/(dashboard)/order-analysis/page.tsx create mode 100644 app/home/(user)/(dashboard)/order-health-analysis/page.tsx diff --git a/app/home/(user)/(dashboard)/order-analysis/page.tsx b/app/home/(user)/(dashboard)/order-analysis/page.tsx new file mode 100644 index 0000000..e8d28ad --- /dev/null +++ b/app/home/(user)/(dashboard)/order-analysis/page.tsx @@ -0,0 +1,28 @@ +import { createI18nServerInstance } from '~/lib/i18n/i18n.server'; +import { withI18n } from '~/lib/i18n/with-i18n'; +import { PageBody } from '@kit/ui/page'; +import { Trans } from '@kit/ui/trans'; +import { HomeLayoutPageHeader } from '../../_components/home-page-header'; + +export const generateMetadata = async () => { + const { t } = await createI18nServerInstance(); + + return { + title: t('order-analysis:title'), + }; +}; + +async function OrderAnalysisPage() { + return ( + <> + } + description={} + /> + + + + ); +} + +export default withI18n(OrderAnalysisPage); diff --git a/app/home/(user)/(dashboard)/order-health-analysis/page.tsx b/app/home/(user)/(dashboard)/order-health-analysis/page.tsx new file mode 100644 index 0000000..6a8524f --- /dev/null +++ b/app/home/(user)/(dashboard)/order-health-analysis/page.tsx @@ -0,0 +1,28 @@ +import { createI18nServerInstance } from '~/lib/i18n/i18n.server'; +import { withI18n } from '~/lib/i18n/with-i18n'; +import { PageBody } from '@kit/ui/page'; +import { Trans } from '@kit/ui/trans'; +import { HomeLayoutPageHeader } from '../../_components/home-page-header'; + +export const generateMetadata = async () => { + const { t } = await createI18nServerInstance(); + + return { + title: t('order-health-analysis:title'), + }; +}; + +async function OrderHealthAnalysisPage() { + return ( + <> + } + description={} + /> + + + + ); +} + +export default withI18n(OrderHealthAnalysisPage); diff --git a/config/paths.config.ts b/config/paths.config.ts index ca6222d..1a2a2d4 100644 --- a/config/paths.config.ts +++ b/config/paths.config.ts @@ -60,10 +60,9 @@ const pathsConfig = PathsSchema.parse({ booking: '/home/booking', orderAnalysisPackage: '/home/order-analysis-package', myOrders: '/home/order', - // these routes are added as placeholders and can be changed when the pages are added analysisResults: '/home/analysis-results', - orderAnalysis: '/order-analysis', - orderHealthAnalysis: '/order-health-analysis', + orderAnalysis: '/home/order-analysis', + orderHealthAnalysis: '/home/order-health-analysis', }, } satisfies z.infer); From 6dcb9ae4dbea931cedafe9cd00e814eb187d7ad3 Mon Sep 17 00:00:00 2001 From: k4rli Date: Thu, 24 Jul 2025 08:40:01 +0300 Subject: [PATCH 09/12] feat(MED-50): apply medusa middleware for cache id --- middleware.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/middleware.ts b/middleware.ts index c9283b7..5632285 100644 --- a/middleware.ts +++ b/middleware.ts @@ -6,6 +6,7 @@ import { CsrfError, createCsrfProtect } from '@edge-csrf/nextjs'; import { isSuperAdmin } from '@kit/admin'; import { checkRequiresMultiFactorAuthentication } from '@kit/supabase/check-requires-mfa'; import { createMiddlewareClient } from '@kit/supabase/middleware-client'; +import { middleware as medusaMiddleware } from "~/medusa/middleware"; import appConfig from '~/config/app.config'; import pathsConfig from '~/config/paths.config'; @@ -53,6 +54,8 @@ export async function middleware(request: NextRequest) { csrfResponse.headers.set('x-action-path', request.nextUrl.pathname); } + await medusaMiddleware(request as any); + // if no pattern handler returned a response, // return the session response return csrfResponse; From d7499fbc136de3d8753d21b754f4e023817ff190 Mon Sep 17 00:00:00 2001 From: k4rli Date: Thu, 24 Jul 2025 08:40:27 +0300 Subject: [PATCH 10/12] feat(MED-50): update default env --- .env | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.env b/.env index 38867a6..4eed429 100644 --- a/.env +++ b/.env @@ -5,7 +5,7 @@ # TO OVERRIDE THESE VARIABLES IN A SPECIFIC ENVIRONMENT, PLEASE ADD THEM TO THE SPECIFIC ENVIRONMENT FILE (e.g. .env.development, .env.production) # SITE -NEXT_PUBLIC_SITE_URL=https://localhost:3000 +NEXT_PUBLIC_SITE_URL=http://localhost:3000 NEXT_PUBLIC_PRODUCT_NAME=MedReport NEXT_PUBLIC_SITE_TITLE="MedReport" NEXT_PUBLIC_SITE_DESCRIPTION="MedReport." @@ -19,7 +19,7 @@ NEXT_PUBLIC_AUTH_MAGIC_LINK=false NEXT_PUBLIC_CAPTCHA_SITE_KEY= # BILLING -NEXT_PUBLIC_BILLING_PROVIDER=stripe +NEXT_PUBLIC_BILLING_PROVIDER=montonio # CMS CMS_CLIENT=keystatic From 3341dbd306b4993381cb9930bf1fb6d7d9409ed3 Mon Sep 17 00:00:00 2001 From: k4rli Date: Thu, 24 Jul 2025 08:52:59 +0300 Subject: [PATCH 11/12] feat(MED-48): improvements --- .../montonio-callback/[montonioId]/route.ts | 13 +- package.json | 1 + .../src/emails/synlab.email.tsx | 4 +- .../src/locales/en/synlab-email.json | 6 +- .../src/locales/et/synlab-email.json | 2 +- pnpm-lock.yaml | 1758 ++++++++++++++++- 6 files changed, 1671 insertions(+), 113 deletions(-) diff --git a/app/home/(user)/(dashboard)/cart/montonio-callback/[montonioId]/route.ts b/app/home/(user)/(dashboard)/cart/montonio-callback/[montonioId]/route.ts index a295b65..b87d810 100644 --- a/app/home/(user)/(dashboard)/cart/montonio-callback/[montonioId]/route.ts +++ b/app/home/(user)/(dashboard)/cart/montonio-callback/[montonioId]/route.ts @@ -1,8 +1,9 @@ -import { MontonioOrderToken } from "@/app/home/(user)/_components/cart/types"; -import { loadCurrentUserAccount } from "@/app/home/(user)/_lib/server/load-user-account"; -import { placeOrder } from "@lib/data/cart"; import jwt from 'jsonwebtoken'; import { z } from "zod"; +import { MontonioOrderToken } from "@/app/home/(user)/_components/cart/types"; +import { loadCurrentUserAccount } from "@/app/home/(user)/_lib/server/load-user-account"; +import { listProductTypes } from "@lib/data/products"; +import { placeOrder } from "@lib/data/cart"; import { createI18nServerInstance } from "~/lib/i18n/i18n.server"; const emailSender = process.env.EMAIL_SENDER; @@ -70,11 +71,13 @@ const handleOrderToken = async (orderToken: string) => { if (!cartId) { throw new Error("Cart ID not found"); } + const { productTypes } = await listProductTypes(); + const analysisPackagesType = productTypes.find(({ metadata }) => metadata?.handle === 'analysis-packages'); const { order } = await placeOrder(cartId, { revalidateCacheTags: true }); return { email: order.email, partnerLocationName: order.metadata?.partner_location_name as string ?? '', - analysisPackageName: order.items?.[0]?.title ?? '', + analysisPackageName: order.items?.find(item => item.product_type_id === analysisPackagesType?.id)?.title ?? '', }; } catch (error) { throw new Error(`Failed to place order, message=${error}`); @@ -102,7 +105,7 @@ export async function GET(request: Request) { const { email, partnerLocationName, analysisPackageName } = orderResult; const personName = account.name; - if (email) { + if (email && analysisPackageName && partnerLocationName) { await sendEmail({ email, analysisPackageName, personName, partnerLocationName, language }); } return Response.redirect(new URL('/home/order', baseUrl)) diff --git a/package.json b/package.json index a042b25..4106646 100644 --- a/package.json +++ b/package.json @@ -68,6 +68,7 @@ "clsx": "^2.1.1", "date-fns": "^4.1.0", "fast-xml-parser": "^5.2.5", + "isikukood": "3.1.7", "jsonwebtoken": "9.0.2", "lodash": "^4.17.21", "lucide-react": "^0.510.0", diff --git a/packages/email-templates/src/emails/synlab.email.tsx b/packages/email-templates/src/emails/synlab.email.tsx index 2dfcf27..57f9f36 100644 --- a/packages/email-templates/src/emails/synlab.email.tsx +++ b/packages/email-templates/src/emails/synlab.email.tsx @@ -32,7 +32,9 @@ export async function renderSynlabAnalysisPackageEmail(props: Props) { }); const previewText = t(`${namespace}:previewText`); - const subject = t(`${namespace}:subject`); + const subject = t(`${namespace}:subject`, { + analysisPackageName: props.analysisPackageName, + }); const heading = t(`${namespace}:heading`, { analysisPackageName: props.analysisPackageName, diff --git a/packages/email-templates/src/locales/en/synlab-email.json b/packages/email-templates/src/locales/en/synlab-email.json index 61b1d94..3270ecc 100644 --- a/packages/email-templates/src/locales/en/synlab-email.json +++ b/packages/email-templates/src/locales/en/synlab-email.json @@ -1,7 +1,7 @@ { - "subject": "Your Synlab order has been placed", - "previewText": "Your Synlab order has been placed", - "heading": "Your Synlab order has been placed", + "subject": "Your Synlab order has been placed - {{analysisPackageName}}", + "previewText": "Your Synlab order has been placed - {{analysisPackageName}}", + "heading": "Your Synlab order has been placed - {{analysisPackageName}}", "hello": "Hello {{personName}},", "lines1": "The order for {{analysisPackageName}} analysis package has been sent to the lab. Please go to the lab to collect the sample: SYNLAB - {{partnerLocationName}}", "lines2": "If you are unable to go to the lab to collect the sample, you can go to any other suitable collection point - view locations and opening hours.", diff --git a/packages/email-templates/src/locales/et/synlab-email.json b/packages/email-templates/src/locales/et/synlab-email.json index 2a9147e..fd11035 100644 --- a/packages/email-templates/src/locales/et/synlab-email.json +++ b/packages/email-templates/src/locales/et/synlab-email.json @@ -1,5 +1,5 @@ { - "subject": "Teie SYNLAB tellimus on kinnitatud", + "subject": "Teie SYNLAB tellimus on kinnitatud - {{analysisPackageName}}", "previewText": "Teie SYNLAB tellimus on kinnitatud - {{analysisPackageName}}", "heading": "Teie SYNLAB tellimus on kinnitatud - {{analysisPackageName}}", "hello": "Tere {{personName}},", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2ac40cd..c457fa7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,7 +10,7 @@ importers: dependencies: '@edge-csrf/nextjs': specifier: 2.5.3-cloudflare-rc1 - version: 2.5.3-cloudflare-rc1(next@15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)) + version: 2.5.3-cloudflare-rc1(next@15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)) '@hookform/resolvers': specifier: ^5.1.1 version: 5.1.1(react-hook-form@7.58.0(react@19.1.0)) @@ -73,7 +73,7 @@ importers: version: 0.0.10(@supabase/postgrest-js@1.19.4)(@supabase/supabase-js@2.49.4) '@makerkit/data-loader-supabase-nextjs': specifier: ^1.2.5 - version: 1.2.5(@supabase/postgrest-js@1.19.4)(@supabase/supabase-js@2.49.4)(@tanstack/react-query@5.76.1(react@19.1.0))(next@15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0) + version: 1.2.5(@supabase/postgrest-js@1.19.4)(@supabase/supabase-js@2.49.4)(@tanstack/react-query@5.76.1(react@19.1.0))(next@15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0) '@marsidev/react-turnstile': specifier: ^1.1.0 version: 1.1.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -88,7 +88,7 @@ importers: version: 4.0.17(@types/react-dom@19.1.5(@types/react@19.1.4))(@types/react@19.1.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3) '@nosecone/next': specifier: 1.0.0-beta.7 - version: 1.0.0-beta.7(next@15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)) + version: 1.0.0-beta.7(next@15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)) '@radix-ui/react-icons': specifier: ^1.3.2 version: 1.3.2(react@19.1.0) @@ -119,6 +119,9 @@ importers: fast-xml-parser: specifier: ^5.2.5 version: 5.2.5 + isikukood: + specifier: 3.1.7 + version: 3.1.7(@babel/core@7.27.4)(@types/node@22.15.32)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.15.32)(typescript@5.8.3)) jsonwebtoken: specifier: 9.0.2 version: 9.0.2 @@ -130,10 +133,10 @@ importers: version: 0.510.0(react@19.1.0) next: specifier: 15.3.2 - version: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) next-sitemap: specifier: ^4.2.3 - version: 4.2.3(next@15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)) + version: 4.2.3(next@15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)) next-themes: specifier: 0.4.6 version: 0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -317,7 +320,7 @@ importers: version: 0.510.0(react@19.1.0) next: specifier: 15.3.2 - version: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: specifier: 19.1.0 version: 19.1.0 @@ -354,7 +357,7 @@ importers: version: 19.1.4 next: specifier: 15.3.2 - version: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: specifier: 19.1.0 version: 19.1.0 @@ -390,7 +393,7 @@ importers: version: 4.1.0 next: specifier: 15.3.2 - version: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: specifier: 19.1.0 version: 19.1.0 @@ -436,7 +439,7 @@ importers: version: 4.1.0 next: specifier: 15.3.2 - version: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: specifier: 19.1.0 version: 19.1.0 @@ -472,10 +475,10 @@ importers: dependencies: '@keystatic/core': specifier: 0.5.47 - version: 0.5.47(next@15.4.0-canary.128(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 0.5.47(next@15.4.0-canary.128(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@keystatic/next': specifier: ^5.0.4 - version: 5.0.4(@keystatic/core@0.5.47(next@15.4.0-canary.128(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(next@15.4.0-canary.128(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 5.0.4(@keystatic/core@0.5.47(next@15.4.0-canary.128(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(next@15.4.0-canary.128(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@markdoc/markdoc': specifier: ^0.5.1 version: 0.5.2(@types/react@19.1.4)(react@19.1.0) @@ -664,7 +667,7 @@ importers: version: 0.510.0(react@19.1.0) next: specifier: 15.3.2 - version: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) next-themes: specifier: 0.4.6 version: 0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -709,7 +712,7 @@ importers: version: 0.0.10(@supabase/postgrest-js@1.19.4)(@supabase/supabase-js@2.49.4) '@makerkit/data-loader-supabase-nextjs': specifier: ^1.2.5 - version: 1.2.5(@supabase/postgrest-js@1.19.4)(@supabase/supabase-js@2.49.4)(@tanstack/react-query@5.76.1(react@19.1.0))(next@15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0) + version: 1.2.5(@supabase/postgrest-js@1.19.4)(@supabase/supabase-js@2.49.4)(@tanstack/react-query@5.76.1(react@19.1.0))(next@15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0) '@supabase/supabase-js': specifier: 2.49.4 version: 2.49.4 @@ -727,7 +730,7 @@ importers: version: 0.510.0(react@19.1.0) next: specifier: 15.3.2 - version: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: specifier: 19.1.0 version: 19.1.0 @@ -778,7 +781,7 @@ importers: version: 0.510.0(react@19.1.0) next: specifier: 15.3.2 - version: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) sonner: specifier: ^2.0.3 version: 2.0.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -808,7 +811,7 @@ importers: version: 4.17.21 next: specifier: ^15.3.1 - version: 15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106) + version: 15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106) pg: specifier: ^8.11.3 version: 8.16.3 @@ -999,7 +1002,7 @@ importers: version: 0.510.0(react@19.1.0) next: specifier: 15.3.2 - version: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: specifier: 19.1.0 version: 19.1.0 @@ -1039,7 +1042,7 @@ importers: version: 5.76.1(react@19.1.0) next: specifier: 15.3.2 - version: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: specifier: 19.1.0 version: 19.1.0 @@ -1209,7 +1212,7 @@ importers: dependencies: '@sentry/nextjs': specifier: ^9.19.0 - version: 9.27.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(next@15.4.0-canary.128(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(webpack@5.99.9) + version: 9.27.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(next@15.4.0-canary.128(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(webpack@5.99.9) import-in-the-middle: specifier: 1.13.2 version: 1.13.2 @@ -1258,7 +1261,7 @@ importers: version: 2.49.4 next: specifier: 15.3.2 - version: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) packages/otp: devDependencies: @@ -1355,7 +1358,7 @@ importers: version: 19.1.4 next: specifier: 15.3.2 - version: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: specifier: 19.1.0 version: 19.1.0 @@ -1487,7 +1490,7 @@ importers: version: 9.28.0(jiti@2.4.2) next: specifier: 15.3.2 - version: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) next-themes: specifier: 0.4.6 version: 0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -1665,6 +1668,10 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -1686,6 +1693,97 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/plugin-syntax-async-generators@7.8.4': + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-bigint@7.8.3': + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-properties@7.12.13': + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-static-block@7.14.5': + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.27.1': + resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-json-strings@7.8.3': + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-numeric-separator@7.10.4': + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-object-rest-spread@7.8.3': + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3': + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-chaining@7.8.3': + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-private-property-in-object@7.14.5': + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-top-level-await@7.14.5': + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.27.1': + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/runtime@7.27.6': resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} engines: {node: '>=6.9.0'} @@ -1712,6 +1810,9 @@ packages: peerDependencies: react: ^18.2.0 + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + '@braintree/sanitize-url@6.0.4': resolution: {integrity: sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==} @@ -2054,6 +2155,80 @@ packages: resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} engines: {node: '>=18.0.0'} + '@istanbuljs/load-nyc-config@1.1.0': + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jest/console@29.7.0': + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/core@29.7.0': + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/environment@29.7.0': + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect-utils@29.7.0': + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect@29.7.0': + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/fake-timers@29.7.0': + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/globals@29.7.0': + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/reporters@29.7.0': + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/source-map@29.6.3': + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-result@29.7.0': + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-sequencer@29.7.0': + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/transform@29.7.0': + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jridgewell/gen-mapping@0.3.8': resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} engines: {node: '>=6.0.0'} @@ -5135,6 +5310,9 @@ packages: peerDependencies: webpack: '>=4.40.0' + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + '@sindresorhus/slugify@1.1.2': resolution: {integrity: sha512-V9nR/W0Xd9TSGXpZ4iFUcFGhuOJtZX82Fzxj1YISlbSgKvIiNa7eLEZrT0vAraPOt++KHauIVNYgGRgjc13dXA==} engines: {node: '>=10'} @@ -5143,6 +5321,12 @@ packages: resolution: {integrity: sha512-5/kmIOY9FF32nicXH+5yLNTX4NJ4atl7jRgqAJuIn/iyDFXBktOKDxCvyGE/EzmF4ngSUvjXxQUQlQiZ5lfw+w==} engines: {node: '>=10'} + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + '@standard-schema/utils@0.3.0': resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} @@ -5388,6 +5572,18 @@ packages: '@types/aws-lambda@8.10.149': resolution: {integrity: sha512-NXSZIhfJjnXqJgtS7IwutqIF/SOy1Wz5Px4gUY1RWITp3AYTyuJS4xaXr/bIJY1v15XMzrJ5soGnPM+7uigZjA==} + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.20.7': + resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} + '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} @@ -5436,12 +5632,24 @@ packages: '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} '@types/is-hotkey@0.1.10': resolution: {integrity: sha512-RvC8KMw5BCac1NvRRyaHgMMEtBaZ6wh0pyPTBu7izn4Sj/AX9Y4aXU5c7rX8PnM/knsuUpC1IeoBkANtxBypsQ==} + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -5533,6 +5741,9 @@ packages: '@types/shimmer@1.2.0': resolution: {integrity: sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==} + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + '@types/tedious@4.0.14': resolution: {integrity: sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==} @@ -5545,6 +5756,12 @@ packages: '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.33': + resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} + '@typescript-eslint/eslint-plugin@8.32.1': resolution: {integrity: sha512-6u6Plg9nP/J1GRpe/vcjjabo6Uc5YQPAMxsgQyGC/I0RuukiG1wIe3+Vtg3IrSCVJDmqK3j8adrtzXSENRtFgg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -5880,6 +6097,10 @@ packages: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -5892,6 +6113,10 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + ansi-styles@6.2.1: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} @@ -5909,6 +6134,9 @@ packages: arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -5992,6 +6220,12 @@ packages: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} + babel-jest@29.7.0: + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + babel-loader@8.4.1: resolution: {integrity: sha512-nXzRChX+Z1GoE6yWavBQg6jDslyFF3SDjl2paADuoQtQW10JqShJt62R6eJQ5m/pjJFDT8xgKIWSP85OY8eXeA==} engines: {node: '>= 8.9'} @@ -5999,6 +6233,14 @@ packages: '@babel/core': ^7.0.0 webpack: '>=2' + babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + + babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + babel-plugin-macros@3.1.0: resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} engines: {node: '>=10', npm: '>=6'} @@ -6006,6 +6248,17 @@ packages: babel-plugin-react-compiler@19.1.0-rc.2: resolution: {integrity: sha512-kSNA//p5fMO6ypG8EkEVPIqAjwIXm5tMjfD1XRPL/sRjYSbJ6UsvORfaeolNWnZ9n310aM0xJP7peW26BuCVzA==} + babel-preset-current-node-syntax@1.1.0: + resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} + peerDependencies: + '@babel/core': ^7.0.0 + + babel-preset-jest@29.6.3: + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -6041,6 +6294,9 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + buffer-equal-constant-time@1.0.1: resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} @@ -6074,6 +6330,14 @@ packages: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} @@ -6091,6 +6355,10 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + character-entities-html4@2.1.0: resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} @@ -6115,6 +6383,10 @@ packages: resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} engines: {node: '>=6.0'} + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + cjs-module-lexer@1.4.3: resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} @@ -6150,6 +6422,13 @@ packages: react: ^18 || ^19 || ^19.0.0-rc react-dom: ^18 || ^19 || ^19.0.0-rc + co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + collect-v8-coverage@1.0.2: + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -6214,6 +6493,11 @@ packages: resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} engines: {node: '>=10'} + create-jest@29.7.0: + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} @@ -6378,6 +6662,14 @@ packages: decode-named-character-reference@1.1.0: resolution: {integrity: sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==} + dedent@1.6.0: + resolution: {integrity: sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -6405,6 +6697,10 @@ packages: resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} engines: {node: '>=8'} + detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + detect-node-es@1.1.0: resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} @@ -6414,6 +6710,10 @@ packages: didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} @@ -6476,6 +6776,10 @@ packages: emery@1.4.4: resolution: {integrity: sha512-mMoO3uGDoiw/DmZ/YekT9gEoC0IFAXNWzYVukY8+/j0Wt8un1IDraIYGx+cMbRh+fHaCDE6Ui7zFAN8ezZSsAA==} + emittery@0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -6700,6 +7004,11 @@ packages: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + esquery@1.6.0: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} @@ -6740,6 +7049,18 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + + expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + facepaint@1.2.1: resolution: {integrity: sha512-oNvBekbhsm/0PNSOWca5raHNAi6dG960Bx6LJgxDPNF59WpuspgQ17bN5MKwOr7JcFdQYc7StW3VZ28DBZLavQ==} @@ -6787,6 +7108,9 @@ packages: fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + fdir@6.4.5: resolution: {integrity: sha512-4BG7puHpVsIYxZUbiUE3RqGloLaSSwzYie5jvasC4LWuBWzZawynvYouhjbQKw2JuIGYdm0DzIxl8iVidKlUEw==} peerDependencies: @@ -6913,10 +7237,18 @@ packages: resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} engines: {node: '>=6'} + get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + get-proto@1.0.1: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + get-symbol-description@1.1.0: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} @@ -7041,6 +7373,10 @@ packages: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + i18next-browser-languagedetector@8.1.0: resolution: {integrity: sha512-mHZxNx1Lq09xt5kCauZ/4bsXOEA2pfpwSoU11/QTJB+pD94iONFwp+ohqi///PwiFvjFOxe1akYCdHyFo1ng5Q==} @@ -7082,6 +7418,11 @@ packages: import-in-the-middle@1.7.1: resolution: {integrity: sha512-1LrZPDtW+atAxH42S6288qyDFNQ2YCty+2mxEPRtfazH6Z5QwkaBSTS2ods7hnVJioF6rkRfNoA6A/MstpFXLg==} + import-local@3.2.0: + resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} + engines: {node: '>=8'} + hasBin: true + imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} @@ -7176,6 +7517,10 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} + is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + is-generator-function@1.1.0: resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} engines: {node: '>= 0.4'} @@ -7228,6 +7573,10 @@ packages: resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} engines: {node: '>= 0.4'} + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + is-string@1.1.1: resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} engines: {node: '>= 0.4'} @@ -7258,9 +7607,36 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isikukood@3.1.7: + resolution: {integrity: sha512-PJMj8R8+2qtquYbpRxAQedgn7haTngotZIxEDEaWzbeFTw3SNfF4TLsfYVTbM9PW1+mQpxHnDTok/GU30VwSqg==} + isomorphic.js@0.2.5: resolution: {integrity: sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==} + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@6.0.3: + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} + engines: {node: '>=10'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + iterator.prototype@1.1.5: resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} engines: {node: '>= 0.4'} @@ -7271,10 +7647,139 @@ packages: javascript-natural-sort@0.7.1: resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==} + jest-changed-files@29.7.0: + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-circus@29.7.0: + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-cli@29.7.0: + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest-config@29.7.0: + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + + jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-docblock@29.7.0: + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-each@29.7.0: + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-leak-detector@29.7.0: + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-pnp-resolver@1.2.3: + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + + jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve-dependencies@29.7.0: + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve@29.7.0: + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runner@29.7.0: + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runtime@29.7.0: + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-snapshot@29.7.0: + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-watcher@29.7.0: + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-worker@27.5.1: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest@29.7.0: + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + jiti@1.21.7: resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true @@ -7294,6 +7799,10 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true @@ -7344,6 +7853,10 @@ packages: keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + language-subtag-registry@0.3.23: resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} @@ -7354,6 +7867,10 @@ packages: leac@0.6.0: resolution: {integrity: sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==} + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -7524,9 +8041,16 @@ packages: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} @@ -7701,6 +8225,10 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + mini-svg-data-uri@1.4.4: resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==} hasBin: true @@ -7849,6 +8377,9 @@ packages: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} @@ -7872,6 +8403,10 @@ packages: resolution: {integrity: sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==} engines: {node: ^18.17.0 || >=20.5.0} + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} @@ -7918,6 +8453,10 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + opener@1.5.2: resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} hasBin: true @@ -8376,6 +8915,10 @@ packages: engines: {node: '>=14'} hasBin: true + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + prism-react-renderer@2.4.1: resolution: {integrity: sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==} peerDependencies: @@ -8396,6 +8939,10 @@ packages: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -8440,6 +8987,9 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + qs@6.14.0: resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} engines: {node: '>=0.6'} @@ -8648,13 +9198,25 @@ packages: resolution: {integrity: sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==} engines: {node: '>=8.6.0'} + resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve.exports@2.0.3: + resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} + engines: {node: '>=10'} + resolve@1.22.10: resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} engines: {node: '>= 0.4'} @@ -8791,6 +9353,9 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} @@ -8802,6 +9367,13 @@ packages: resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} engines: {node: '>= 10'} + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + slate-history@0.86.0: resolution: {integrity: sha512-OxObL9tbhgwvSlnKSCpGIh7wnuaqvOj5jRExGjEyCU2Ke8ctf22HjT+jw7GEi9ttLzNTUmTEU3YIzqKGeqN+og==} peerDependencies: @@ -8836,6 +9408,9 @@ packages: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} @@ -8851,9 +9426,16 @@ packages: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + stable-hash@0.0.5: resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} + stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + stacktrace-parser@0.1.11: resolution: {integrity: sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==} engines: {node: '>=6'} @@ -8866,6 +9448,10 @@ packages: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} + string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -8912,6 +9498,14 @@ packages: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} + strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -9041,6 +9635,10 @@ packages: engines: {node: '>=10'} hasBin: true + test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} @@ -9070,6 +9668,9 @@ packages: resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} engines: {node: '>=12.0.0'} + tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -9157,10 +9758,18 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + type-fest@0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + type-fest@0.7.1: resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} engines: {node: '>=8'} @@ -9285,6 +9894,10 @@ packages: v8-compile-cache@2.4.0: resolution: {integrity: sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==} + v8-to-istanbul@9.3.0: + resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} + engines: {node: '>=10.12.0'} + vfile-message@4.0.2: resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} @@ -9298,6 +9911,9 @@ packages: w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + watchpack@2.4.4: resolution: {integrity: sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==} engines: {node: '>=10.13.0'} @@ -9379,6 +9995,10 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + write-file-atomic@6.0.0: resolution: {integrity: sha512-GmqrO8WJ1NuzJ2DrziEI2o57jKAVIQNf8a18W3nCYU3H7PNWqCCVTeH6/NQE93CIllIgQS98rrmVkYgTX9fFJQ==} engines: {node: ^18.17.0 || >=20.5.0} @@ -9633,6 +10253,8 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-plugin-utils@7.27.1': {} + '@babel/helper-string-parser@7.27.1': {} '@babel/helper-validator-identifier@7.27.1': {} @@ -9648,6 +10270,91 @@ snapshots: dependencies: '@babel/types': 7.27.6 + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/runtime@7.27.6': {} '@babel/template@7.27.2': @@ -9699,6 +10406,8 @@ snapshots: react-error-boundary: 4.1.2(react@19.1.0) web-vitals: 3.5.2 + '@bcoe/v8-coverage@0.2.3': {} + '@braintree/sanitize-url@6.0.4': {} '@corex/deepmerge@4.0.43': {} @@ -9709,9 +10418,9 @@ snapshots: '@discoveryjs/json-ext@0.5.7': {} - '@edge-csrf/nextjs@2.5.3-cloudflare-rc1(next@15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))': + '@edge-csrf/nextjs@2.5.3-cloudflare-rc1(next@15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))': dependencies: - next: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next: 15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@emnapi/core@1.4.3': dependencies: @@ -10083,6 +10792,178 @@ snapshots: dependencies: minipass: 7.1.2 + '@istanbuljs/load-nyc-config@1.1.0': + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + + '@istanbuljs/schema@0.1.3': {} + + '@jest/console@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@types/node': 22.15.32 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + + '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.15.32)(typescript@5.8.3))': + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.15.32 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@22.15.32)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.15.32)(typescript@5.8.3)) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + + '@jest/environment@29.7.0': + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.15.32 + jest-mock: 29.7.0 + + '@jest/expect-utils@29.7.0': + dependencies: + jest-get-type: 29.6.3 + + '@jest/expect@29.7.0': + dependencies: + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/fake-timers@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 22.15.32 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + '@jest/globals@29.7.0': + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/reporters@29.7.0': + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + '@types/node': 22.15.32 + chalk: 4.1.2 + collect-v8-coverage: 1.0.2 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.7 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.3.0 + transitivePeerDependencies: + - supports-color + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jest/source-map@29.6.3': + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + callsites: 3.1.0 + graceful-fs: 4.2.11 + + '@jest/test-result@29.7.0': + dependencies: + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.2 + + '@jest/test-sequencer@29.7.0': + dependencies: + '@jest/test-result': 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 + + '@jest/transform@29.7.0': + dependencies: + '@babel/core': 7.27.4 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.8 + pirates: 4.0.7 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 22.15.32 + '@types/yargs': 17.0.33 + chalk: 4.1.2 + '@jridgewell/gen-mapping@0.3.8': dependencies: '@jridgewell/set-array': 1.2.1 @@ -10114,7 +10995,7 @@ snapshots: '@juggle/resize-observer@3.4.0': {} - '@keystar/ui@0.7.19(next@15.4.0-canary.128(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@keystar/ui@0.7.19(next@15.4.0-canary.128(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@babel/runtime': 7.27.6 '@emotion/css': 11.13.5 @@ -10207,18 +11088,18 @@ snapshots: react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - next: 15.4.0-canary.128(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next: 15.4.0-canary.128(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) transitivePeerDependencies: - supports-color - '@keystatic/core@0.5.47(next@15.4.0-canary.128(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@keystatic/core@0.5.47(next@15.4.0-canary.128(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@babel/runtime': 7.27.6 '@braintree/sanitize-url': 6.0.4 '@emotion/weak-memoize': 0.3.1 '@floating-ui/react': 0.24.8(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@internationalized/string': 3.2.7 - '@keystar/ui': 0.7.19(next@15.4.0-canary.128(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@keystar/ui': 0.7.19(next@15.4.0-canary.128(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@markdoc/markdoc': 0.4.0(@types/react@19.1.4)(react@19.1.0) '@react-aria/focus': 3.20.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@react-aria/i18n': 3.12.10(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -10289,13 +11170,13 @@ snapshots: - next - supports-color - '@keystatic/next@5.0.4(@keystatic/core@0.5.47(next@15.4.0-canary.128(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(next@15.4.0-canary.128(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@keystatic/next@5.0.4(@keystatic/core@0.5.47(next@15.4.0-canary.128(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(next@15.4.0-canary.128(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@babel/runtime': 7.27.6 - '@keystatic/core': 0.5.47(next@15.4.0-canary.128(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@keystatic/core': 0.5.47(next@15.4.0-canary.128(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@types/react': 19.1.4 chokidar: 3.6.0 - next: 15.4.0-canary.128(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next: 15.4.0-canary.128(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) server-only: 0.0.1 @@ -10308,12 +11189,12 @@ snapshots: '@supabase/supabase-js': 2.49.4 ts-case-convert: 2.1.0 - '@makerkit/data-loader-supabase-nextjs@1.2.5(@supabase/postgrest-js@1.19.4)(@supabase/supabase-js@2.49.4)(@tanstack/react-query@5.76.1(react@19.1.0))(next@15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)': + '@makerkit/data-loader-supabase-nextjs@1.2.5(@supabase/postgrest-js@1.19.4)(@supabase/supabase-js@2.49.4)(@tanstack/react-query@5.76.1(react@19.1.0))(next@15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)': dependencies: '@makerkit/data-loader-supabase-core': 0.0.10(@supabase/postgrest-js@1.19.4)(@supabase/supabase-js@2.49.4) '@supabase/supabase-js': 2.49.4 '@tanstack/react-query': 5.76.1(react@19.1.0) - next: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next: 15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: 19.1.0 transitivePeerDependencies: - '@supabase/postgrest-js' @@ -10509,9 +11390,9 @@ snapshots: '@nolyfill/is-core-module@1.0.39': {} - '@nosecone/next@1.0.0-beta.7(next@15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))': + '@nosecone/next@1.0.0-beta.7(next@15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))': dependencies: - next: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next: 15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) nosecone: 1.0.0-beta.7 '@opentelemetry/api-logs@0.50.0': @@ -15881,7 +16762,7 @@ snapshots: '@sentry/core@9.27.0': {} - '@sentry/nextjs@9.27.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(next@15.4.0-canary.128(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(webpack@5.99.9)': + '@sentry/nextjs@9.27.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(next@15.4.0-canary.128(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(webpack@5.99.9)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/semantic-conventions': 1.34.0 @@ -15894,7 +16775,7 @@ snapshots: '@sentry/vercel-edge': 9.27.0 '@sentry/webpack-plugin': 3.5.0(webpack@5.99.9) chalk: 3.0.0 - next: 15.4.0-canary.128(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next: 15.4.0-canary.128(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) resolve: 1.22.8 rollup: 4.35.0 stacktrace-parser: 0.1.11 @@ -15979,6 +16860,8 @@ snapshots: - encoding - supports-color + '@sinclair/typebox@0.27.8': {} + '@sindresorhus/slugify@1.1.2': dependencies: '@sindresorhus/transliterate': 0.1.2 @@ -15989,6 +16872,14 @@ snapshots: escape-string-regexp: 2.0.0 lodash.deburr: 4.1.0 + '@sinonjs/commons@3.0.1': + dependencies: + type-detect: 4.0.8 + + '@sinonjs/fake-timers@10.3.0': + dependencies: + '@sinonjs/commons': 3.0.1 + '@standard-schema/utils@0.3.0': {} '@stripe/react-stripe-js@1.16.5(@stripe/stripe-js@1.54.2)(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106)': @@ -16231,6 +17122,27 @@ snapshots: '@types/aws-lambda@8.10.149': {} + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.27.5 + '@babel/types': 7.27.6 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.7 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.27.6 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.27.5 + '@babel/types': 7.27.6 + + '@types/babel__traverse@7.20.7': + dependencies: + '@babel/types': 7.27.6 + '@types/connect@3.4.38': dependencies: '@types/node': 22.15.32 @@ -16281,12 +17193,26 @@ snapshots: '@types/estree@1.0.8': {} + '@types/graceful-fs@4.1.9': + dependencies: + '@types/node': 22.15.32 + '@types/hast@3.0.4': dependencies: '@types/unist': 3.0.3 '@types/is-hotkey@0.1.10': {} + '@types/istanbul-lib-coverage@2.0.6': {} + + '@types/istanbul-lib-report@3.0.3': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + + '@types/istanbul-reports@3.0.4': + dependencies: + '@types/istanbul-lib-report': 3.0.3 + '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} @@ -16393,6 +17319,8 @@ snapshots: '@types/shimmer@1.2.0': {} + '@types/stack-utils@2.0.3': {} + '@types/tedious@4.0.14': dependencies: '@types/node': 22.15.32 @@ -16405,6 +17333,12 @@ snapshots: dependencies: '@types/node': 22.15.32 + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.33': + dependencies: + '@types/yargs-parser': 21.0.3 + '@typescript-eslint/eslint-plugin@8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -16865,6 +17799,10 @@ snapshots: ansi-colors@4.1.3: {} + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + ansi-regex@5.0.1: {} ansi-regex@6.1.0: {} @@ -16873,6 +17811,8 @@ snapshots: dependencies: color-convert: 2.0.1 + ansi-styles@5.2.0: {} + ansi-styles@6.2.1: {} any-promise@1.3.0: {} @@ -16886,6 +17826,10 @@ snapshots: arg@5.0.2: {} + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + argparse@2.0.1: {} aria-hidden@1.2.6: @@ -17000,6 +17944,19 @@ snapshots: axobject-query@4.1.0: {} + babel-jest@29.7.0(@babel/core@7.27.4): + dependencies: + '@babel/core': 7.27.4 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.27.4) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + babel-loader@8.4.1(@babel/core@7.27.4)(webpack@5.99.9): dependencies: '@babel/core': 7.27.4 @@ -17009,6 +17966,23 @@ snapshots: schema-utils: 2.7.1 webpack: 5.99.9 + babel-plugin-istanbul@6.1.1: + dependencies: + '@babel/helper-plugin-utils': 7.27.1 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-jest-hoist@29.6.3: + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.27.6 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.20.7 + babel-plugin-macros@3.1.0: dependencies: '@babel/runtime': 7.27.6 @@ -17019,6 +17993,31 @@ snapshots: dependencies: '@babel/types': 7.27.6 + babel-preset-current-node-syntax@1.1.0(@babel/core@7.27.4): + dependencies: + '@babel/core': 7.27.4 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.27.4) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.27.4) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.27.4) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.27.4) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.27.4) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.27.4) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.27.4) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.27.4) + + babel-preset-jest@29.6.3(@babel/core@7.27.4): + dependencies: + '@babel/core': 7.27.4 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.4) + balanced-match@1.0.2: {} big.js@5.2.2: {} @@ -17057,6 +18056,10 @@ snapshots: node-releases: 2.0.19 update-browserslist-db: 1.1.3(browserslist@4.25.0) + bser@2.1.1: + dependencies: + node-int64: 0.4.0 + buffer-equal-constant-time@1.0.1: {} buffer-from@1.1.2: {} @@ -17091,6 +18094,10 @@ snapshots: camelcase-css@2.0.1: {} + camelcase@5.3.1: {} + + camelcase@6.3.0: {} + caniuse-api@3.0.0: dependencies: browserslist: 4.25.0 @@ -17112,6 +18119,8 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + char-regex@1.0.2: {} + character-entities-html4@2.1.0: {} character-entities-legacy@3.0.0: {} @@ -17136,6 +18145,8 @@ snapshots: chrome-trace-event@1.0.4: {} + ci-info@3.9.0: {} + cjs-module-lexer@1.4.3: {} class-variance-authority@0.7.1: @@ -17170,6 +18181,10 @@ snapshots: - '@types/react' - '@types/react-dom' + co@4.6.0: {} + + collect-v8-coverage@1.0.2: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -17228,6 +18243,21 @@ snapshots: path-type: 4.0.0 yaml: 1.10.2 + create-jest@29.7.0(@types/node@22.15.32)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.15.32)(typescript@5.8.3)): + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@22.15.32)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.15.32)(typescript@5.8.3)) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + create-require@1.1.1: {} cross-spawn@7.0.6: @@ -17400,6 +18430,10 @@ snapshots: dependencies: character-entities: 2.0.2 + dedent@1.6.0(babel-plugin-macros@3.1.0): + optionalDependencies: + babel-plugin-macros: 3.1.0 + deep-is@0.1.4: {} deepmerge@4.3.1: {} @@ -17422,6 +18456,8 @@ snapshots: detect-libc@2.0.4: {} + detect-newline@3.1.0: {} + detect-node-es@1.1.0: {} devlop@1.1.0: @@ -17430,6 +18466,8 @@ snapshots: didyoumean@1.2.2: {} + diff-sequences@29.6.3: {} + diff@4.0.2: {} direction@1.0.4: {} @@ -17489,6 +18527,8 @@ snapshots: emery@1.4.4: {} + emittery@0.13.1: {} + emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} @@ -17629,8 +18669,8 @@ snapshots: '@typescript-eslint/parser': 8.33.1(eslint@8.10.0)(typescript@5.8.3) eslint: 8.10.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0)(eslint@8.10.0) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint@8.10.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint@8.10.0))(eslint@8.10.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint@8.10.0))(eslint@8.10.0))(eslint@8.10.0) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.10.0) eslint-plugin-react: 7.37.5(eslint@8.10.0) eslint-plugin-react-hooks: 5.2.0(eslint@8.10.0) @@ -17649,8 +18689,8 @@ snapshots: '@typescript-eslint/parser': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) eslint: 9.28.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0)(eslint@9.28.0(jiti@2.4.2)) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.28.0(jiti@2.4.2)) eslint-plugin-react: 7.37.5(eslint@9.28.0(jiti@2.4.2)) eslint-plugin-react-hooks: 5.2.0(eslint@9.28.0(jiti@2.4.2)) @@ -17675,22 +18715,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0)(eslint@8.10.0): - dependencies: - '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.1 - eslint: 8.10.0 - get-tsconfig: 4.10.1 - is-bun-module: 2.0.0 - stable-hash: 0.0.5 - tinyglobby: 0.2.14 - unrs-resolver: 1.7.11 - optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint@8.10.0) - transitivePeerDependencies: - - supports-color - - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0)(eslint@9.28.0(jiti@2.4.2)): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.1 @@ -17701,62 +18726,48 @@ snapshots: tinyglobby: 0.2.14 unrs-resolver: 1.7.11 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.10.0): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint@8.10.0))(eslint@8.10.0): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.1 + eslint: 8.10.0 + get-tsconfig: 4.10.1 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 + tinyglobby: 0.2.14 + unrs-resolver: 1.7.11 + optionalDependencies: + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint@8.10.0))(eslint@8.10.0))(eslint@8.10.0) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint@8.10.0))(eslint@8.10.0))(eslint@8.10.0): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.33.1(eslint@8.10.0)(typescript@5.8.3) eslint: 8.10.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0)(eslint@8.10.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint@8.10.0))(eslint@8.10.0) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.28.0(jiti@2.4.2)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) eslint: 9.28.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0)(eslint@9.28.0(jiti@2.4.2)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2)): - dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.9 - array.prototype.findlastindex: 1.2.6 - array.prototype.flat: 1.3.3 - array.prototype.flatmap: 1.3.3 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 9.28.0(jiti@2.4.2) - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.28.0(jiti@2.4.2)) - hasown: 2.0.2 - is-core-module: 2.16.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.1 - semver: 6.3.1 - string.prototype.trimend: 1.0.9 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 8.32.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint@8.10.0): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint@8.10.0))(eslint@8.10.0))(eslint@8.10.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -17767,7 +18778,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.10.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.10.0) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint@8.10.0))(eslint@8.10.0))(eslint@8.10.0) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -17785,6 +18796,35 @@ snapshots: - eslint-import-resolver-webpack - supports-color + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.28.0(jiti@2.4.2) + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + eslint-plugin-jsx-a11y@6.10.2(eslint@8.10.0): dependencies: aria-query: 5.3.2 @@ -18001,6 +19041,8 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.15.0) eslint-visitor-keys: 3.4.3 + esprima@4.0.1: {} + esquery@1.6.0: dependencies: estraverse: 5.3.0 @@ -18030,6 +19072,28 @@ snapshots: events@3.3.0: {} + execa@5.1.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + exit@0.1.2: {} + + expect@29.7.0: + dependencies: + '@jest/expect-utils': 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + facepaint@1.2.1: {} fast-copy@3.0.2: {} @@ -18074,6 +19138,10 @@ snapshots: dependencies: reusify: 1.1.0 + fb-watchman@2.0.2: + dependencies: + bser: 2.1.1 + fdir@6.4.5(picomatch@4.0.2): optionalDependencies: picomatch: 4.0.2 @@ -18196,11 +19264,15 @@ snapshots: get-nonce@1.0.1: {} + get-package-type@0.1.0: {} + get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 es-object-atoms: 1.1.1 + get-stream@6.0.1: {} + get-symbol-description@1.1.0: dependencies: call-bound: 1.0.4 @@ -18339,6 +19411,8 @@ snapshots: transitivePeerDependencies: - supports-color + human-signals@2.1.0: {} + i18next-browser-languagedetector@8.1.0: dependencies: '@babel/runtime': 7.27.6 @@ -18382,6 +19456,11 @@ snapshots: cjs-module-lexer: 1.4.3 module-details-from-path: 1.0.4 + import-local@3.2.0: + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + imurmurhash@0.1.4: {} inflight@1.0.6: @@ -18481,6 +19560,8 @@ snapshots: is-fullwidth-code-point@3.0.0: {} + is-generator-fn@2.1.0: {} + is-generator-function@1.1.0: dependencies: call-bound: 1.0.4 @@ -18528,6 +19609,8 @@ snapshots: dependencies: call-bound: 1.0.4 + is-stream@2.0.1: {} + is-string@1.1.1: dependencies: call-bound: 1.0.4 @@ -18558,8 +19641,61 @@ snapshots: isexe@2.0.0: {} + isikukood@3.1.7(@babel/core@7.27.4)(@types/node@22.15.32)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.15.32)(typescript@5.8.3)): + dependencies: + babel-jest: 29.7.0(@babel/core@7.27.4) + jest: 29.7.0(@types/node@22.15.32)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.15.32)(typescript@5.8.3)) + transitivePeerDependencies: + - '@babel/core' + - '@types/node' + - babel-plugin-macros + - node-notifier + - supports-color + - ts-node + isomorphic.js@0.2.5: {} + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-instrument@5.2.1: + dependencies: + '@babel/core': 7.27.4 + '@babel/parser': 7.27.5 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + istanbul-lib-instrument@6.0.3: + dependencies: + '@babel/core': 7.27.4 + '@babel/parser': 7.27.5 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 7.7.2 + transitivePeerDependencies: + - supports-color + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@4.0.1: + dependencies: + debug: 4.4.1 + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.1.7: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + iterator.prototype@1.1.5: dependencies: define-data-property: 1.1.4 @@ -18577,12 +19713,321 @@ snapshots: javascript-natural-sort@0.7.1: {} + jest-changed-files@29.7.0: + dependencies: + execa: 5.1.1 + jest-util: 29.7.0 + p-limit: 3.1.0 + + jest-circus@29.7.0(babel-plugin-macros@3.1.0): + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.15.32 + chalk: 4.1.2 + co: 4.6.0 + dedent: 1.6.0(babel-plugin-macros@3.1.0) + is-generator-fn: 2.1.0 + jest-each: 29.7.0 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + p-limit: 3.1.0 + pretty-format: 29.7.0 + pure-rand: 6.1.0 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-cli@29.7.0(@types/node@22.15.32)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.15.32)(typescript@5.8.3)): + dependencies: + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.15.32)(typescript@5.8.3)) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@22.15.32)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.15.32)(typescript@5.8.3)) + exit: 0.1.2 + import-local: 3.2.0 + jest-config: 29.7.0(@types/node@22.15.32)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.15.32)(typescript@5.8.3)) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + jest-config@29.7.0(@types/node@22.15.32)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.15.32)(typescript@5.8.3)): + dependencies: + '@babel/core': 7.27.4 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.27.4) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0(babel-plugin-macros@3.1.0) + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 22.15.32 + ts-node: 10.9.2(@types/node@22.15.32)(typescript@5.8.3) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-diff@29.7.0: + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-docblock@29.7.0: + dependencies: + detect-newline: 3.1.0 + + jest-each@29.7.0: + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + jest-get-type: 29.6.3 + jest-util: 29.7.0 + pretty-format: 29.7.0 + + jest-environment-node@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.15.32 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + jest-get-type@29.6.3: {} + + jest-haste-map@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 22.15.32 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + jest-worker: 29.7.0 + micromatch: 4.0.8 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + + jest-leak-detector@29.7.0: + dependencies: + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-matcher-utils@29.7.0: + dependencies: + chalk: 4.1.2 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-message-util@29.7.0: + dependencies: + '@babel/code-frame': 7.27.1 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + stack-utils: 2.0.6 + + jest-mock@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 22.15.32 + jest-util: 29.7.0 + + jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): + optionalDependencies: + jest-resolve: 29.7.0 + + jest-regex-util@29.6.3: {} + + jest-resolve-dependencies@29.7.0: + dependencies: + jest-regex-util: 29.6.3 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + jest-resolve@29.7.0: + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + resolve: 1.22.10 + resolve.exports: 2.0.3 + slash: 3.0.0 + + jest-runner@29.7.0: + dependencies: + '@jest/console': 29.7.0 + '@jest/environment': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.15.32 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.11 + jest-docblock: 29.7.0 + jest-environment-node: 29.7.0 + jest-haste-map: 29.7.0 + jest-leak-detector: 29.7.0 + jest-message-util: 29.7.0 + jest-resolve: 29.7.0 + jest-runtime: 29.7.0 + jest-util: 29.7.0 + jest-watcher: 29.7.0 + jest-worker: 29.7.0 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + + jest-runtime@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/globals': 29.7.0 + '@jest/source-map': 29.6.3 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.15.32 + chalk: 4.1.2 + cjs-module-lexer: 1.4.3 + collect-v8-coverage: 1.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + + jest-snapshot@29.7.0: + dependencies: + '@babel/core': 7.27.4 + '@babel/generator': 7.27.5 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.4) + '@babel/types': 7.27.6 + '@jest/expect-utils': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.4) + chalk: 4.1.2 + expect: 29.7.0 + graceful-fs: 4.2.11 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + natural-compare: 1.4.0 + pretty-format: 29.7.0 + semver: 7.7.2 + transitivePeerDependencies: + - supports-color + + jest-util@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 22.15.32 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + + jest-validate@29.7.0: + dependencies: + '@jest/types': 29.6.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.6.3 + leven: 3.1.0 + pretty-format: 29.7.0 + + jest-watcher@29.7.0: + dependencies: + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.15.32 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 29.7.0 + string-length: 4.0.2 + jest-worker@27.5.1: dependencies: '@types/node': 22.15.32 merge-stream: 2.0.0 supports-color: 8.1.1 + jest-worker@29.7.0: + dependencies: + '@types/node': 22.15.32 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest@29.7.0(@types/node@22.15.32)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.15.32)(typescript@5.8.3)): + dependencies: + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.15.32)(typescript@5.8.3)) + '@jest/types': 29.6.3 + import-local: 3.2.0 + jest-cli: 29.7.0(@types/node@22.15.32)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.15.32)(typescript@5.8.3)) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jiti@1.21.7: {} jiti@2.4.2: {} @@ -18593,6 +20038,11 @@ snapshots: js-tokens@4.0.0: {} + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + js-yaml@4.1.0: dependencies: argparse: 2.0.1 @@ -18650,6 +20100,8 @@ snapshots: dependencies: json-buffer: 3.0.1 + kleur@3.0.3: {} + language-subtag-registry@0.3.23: {} language-tags@1.0.9: @@ -18658,6 +20110,8 @@ snapshots: leac@0.6.0: {} + leven@3.1.0: {} + levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -18792,8 +20246,16 @@ snapshots: dependencies: semver: 6.3.1 + make-dir@4.0.0: + dependencies: + semver: 7.7.2 + make-error@1.3.6: {} + makeerror@1.0.12: + dependencies: + tmpl: 1.0.5 + markdown-table@3.0.4: {} marked@7.0.4: {} @@ -19179,6 +20641,8 @@ snapshots: dependencies: mime-db: 1.52.0 + mimic-fn@2.1.0: {} + mini-svg-data-uri@1.4.4: {} minimatch@3.1.2: @@ -19227,13 +20691,13 @@ snapshots: neo-async@2.6.2: {} - next-sitemap@4.2.3(next@15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)): + next-sitemap@4.2.3(next@15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)): dependencies: '@corex/deepmerge': 4.0.43 '@next/env': 13.5.11 fast-glob: 3.3.3 minimist: 1.2.8 - next: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next: 15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) next-themes@0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: @@ -19244,7 +20708,7 @@ snapshots: dependencies: enhanced-resolve: 5.18.1 - next@15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106): + next@15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106): dependencies: '@next/env': 15.3.2 '@swc/counter': 0.1.3 @@ -19254,7 +20718,7 @@ snapshots: postcss: 8.4.31 react: 19.0.0-rc-66855b96-20241106 react-dom: 19.0.0-rc-66855b96-20241106(react@19.0.0-rc-66855b96-20241106) - styled-jsx: 5.1.6(@babel/core@7.27.4)(react@19.0.0-rc-66855b96-20241106) + styled-jsx: 5.1.6(@babel/core@7.27.4)(babel-plugin-macros@3.1.0)(react@19.0.0-rc-66855b96-20241106) optionalDependencies: '@next/swc-darwin-arm64': 15.3.2 '@next/swc-darwin-x64': 15.3.2 @@ -19271,7 +20735,7 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + next@15.3.2(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: '@next/env': 15.3.2 '@swc/counter': 0.1.3 @@ -19281,7 +20745,7 @@ snapshots: postcss: 8.4.31 react: 19.1.0 react-dom: 19.1.0(react@19.1.0) - styled-jsx: 5.1.6(react@19.1.0) + styled-jsx: 5.1.6(@babel/core@7.27.4)(babel-plugin-macros@3.1.0)(react@19.1.0) optionalDependencies: '@next/swc-darwin-arm64': 15.3.2 '@next/swc-darwin-x64': 15.3.2 @@ -19298,7 +20762,7 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@15.4.0-canary.128(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + next@15.4.0-canary.128(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: '@next/env': 15.4.0-canary.128 '@swc/helpers': 0.5.15 @@ -19306,7 +20770,7 @@ snapshots: postcss: 8.4.31 react: 19.1.0 react-dom: 19.1.0(react@19.1.0) - styled-jsx: 5.1.6(react@19.1.0) + styled-jsx: 5.1.6(@babel/core@7.27.4)(babel-plugin-macros@3.1.0)(react@19.1.0) optionalDependencies: '@next/swc-darwin-arm64': 15.4.0-canary.128 '@next/swc-darwin-x64': 15.4.0-canary.128 @@ -19340,6 +20804,8 @@ snapshots: fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 + node-int64@0.4.0: {} + node-releases@2.0.19: {} nodemailer@7.0.3: {} @@ -19352,6 +20818,10 @@ snapshots: npm-normalize-package-bin@4.0.0: {} + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + nth-check@2.1.1: dependencies: boolbase: 1.0.0 @@ -19406,6 +20876,10 @@ snapshots: dependencies: wrappy: 1.0.2 + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + opener@1.5.2: {} optionator@0.9.4: @@ -19806,6 +21280,12 @@ snapshots: prettier@3.5.3: {} + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + prism-react-renderer@2.4.1(react@19.0.0-rc-66855b96-20241106): dependencies: '@types/prismjs': 1.26.5 @@ -19826,6 +21306,11 @@ snapshots: progress@2.0.3: {} + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + prop-types@15.8.1: dependencies: loose-envify: 1.4.0 @@ -19904,6 +21389,8 @@ snapshots: punycode@2.3.1: {} + pure-rand@6.1.0: {} + qs@6.14.0: dependencies: side-channel: 1.1.0 @@ -20384,10 +21871,18 @@ snapshots: transitivePeerDependencies: - supports-color + resolve-cwd@3.0.0: + dependencies: + resolve-from: 5.0.0 + resolve-from@4.0.0: {} + resolve-from@5.0.0: {} + resolve-pkg-maps@1.0.0: {} + resolve.exports@2.0.3: {} + resolve@1.22.10: dependencies: is-core-module: 2.16.1 @@ -20594,6 +22089,8 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 + signal-exit@3.0.7: {} + signal-exit@4.1.0: {} simple-swizzle@0.2.2: @@ -20607,6 +22104,10 @@ snapshots: mrmime: 2.0.1 totalist: 3.0.1 + sisteransi@1.0.5: {} + + slash@3.0.0: {} + slate-history@0.86.0(slate@0.91.4): dependencies: is-plain-object: 5.0.0 @@ -20654,6 +22155,11 @@ snapshots: source-map-js@1.2.1: {} + source-map-support@0.5.13: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + source-map-support@0.5.21: dependencies: buffer-from: 1.1.2 @@ -20665,8 +22171,14 @@ snapshots: split2@4.2.0: {} + sprintf-js@1.0.3: {} + stable-hash@0.0.5: {} + stack-utils@2.0.6: + dependencies: + escape-string-regexp: 2.0.0 + stacktrace-parser@0.1.11: dependencies: type-fest: 0.7.1 @@ -20678,6 +22190,11 @@ snapshots: streamsearch@1.1.0: {} + string-length@4.0.2: + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -20755,6 +22272,10 @@ snapshots: strip-bom@3.0.0: {} + strip-bom@4.0.0: {} + + strip-final-newline@2.0.0: {} + strip-json-comments@3.1.1: {} stripe@18.2.1(@types/node@24.0.3): @@ -20765,17 +22286,21 @@ snapshots: strnum@2.1.1: {} - styled-jsx@5.1.6(@babel/core@7.27.4)(react@19.0.0-rc-66855b96-20241106): + styled-jsx@5.1.6(@babel/core@7.27.4)(babel-plugin-macros@3.1.0)(react@19.0.0-rc-66855b96-20241106): dependencies: client-only: 0.0.1 react: 19.0.0-rc-66855b96-20241106 optionalDependencies: '@babel/core': 7.27.4 + babel-plugin-macros: 3.1.0 - styled-jsx@5.1.6(react@19.1.0): + styled-jsx@5.1.6(@babel/core@7.27.4)(babel-plugin-macros@3.1.0)(react@19.1.0): dependencies: client-only: 0.0.1 react: 19.1.0 + optionalDependencies: + '@babel/core': 7.27.4 + babel-plugin-macros: 3.1.0 stylehacks@7.0.5(postcss@8.5.6): dependencies: @@ -20902,6 +22427,12 @@ snapshots: commander: 2.20.3 source-map-support: 0.5.21 + test-exclude@6.0.0: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + text-table@0.2.0: {} thenify-all@1.6.0: @@ -20929,6 +22460,8 @@ snapshots: fdir: 6.4.5(picomatch@4.0.2) picomatch: 4.0.2 + tmpl@1.0.5: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -21026,8 +22559,12 @@ snapshots: dependencies: prelude-ls: 1.2.1 + type-detect@4.0.8: {} + type-fest@0.20.2: {} + type-fest@0.21.3: {} + type-fest@0.7.1: {} type-fest@2.19.0: {} @@ -21205,6 +22742,12 @@ snapshots: v8-compile-cache@2.4.0: {} + v8-to-istanbul@9.3.0: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 + vfile-message@4.0.2: dependencies: '@types/unist': 3.0.3 @@ -21231,6 +22774,10 @@ snapshots: w3c-keyname@2.2.8: {} + walker@1.0.8: + dependencies: + makeerror: 1.0.12 + watchpack@2.4.4: dependencies: glob-to-regexp: 0.4.1 @@ -21368,6 +22915,11 @@ snapshots: wrappy@1.0.2: {} + write-file-atomic@4.0.2: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + write-file-atomic@6.0.0: dependencies: imurmurhash: 0.1.4 From 894cf1b454a94c6e67772548fe620955a1f23745 Mon Sep 17 00:00:00 2001 From: k4rli Date: Thu, 24 Jul 2025 09:23:44 +0300 Subject: [PATCH 12/12] feat(MED-100): partner location metadata stored on order line instead of order --- .../montonio-callback/[montonioId]/route.ts | 11 ++++++---- .../order/[orderId]/confirmed/page.tsx | 5 ++++- .../_components/cart/analysis-location.tsx | 22 +++++++++++-------- app/home/(user)/_components/cart/index.tsx | 2 +- .../(user)/_components/order/order-item.tsx | 2 +- .../medusa-storefront/src/lib/data/cart.ts | 7 ++++-- 6 files changed, 31 insertions(+), 18 deletions(-) diff --git a/app/home/(user)/(dashboard)/cart/montonio-callback/[montonioId]/route.ts b/app/home/(user)/(dashboard)/cart/montonio-callback/[montonioId]/route.ts index b87d810..0769f7c 100644 --- a/app/home/(user)/(dashboard)/cart/montonio-callback/[montonioId]/route.ts +++ b/app/home/(user)/(dashboard)/cart/montonio-callback/[montonioId]/route.ts @@ -73,11 +73,12 @@ const handleOrderToken = async (orderToken: string) => { } const { productTypes } = await listProductTypes(); const analysisPackagesType = productTypes.find(({ metadata }) => metadata?.handle === 'analysis-packages'); - const { order } = await placeOrder(cartId, { revalidateCacheTags: true }); + const order = await placeOrder(cartId, { revalidateCacheTags: true }); + const analysisPackageOrderItem = order.items?.find(({ product_type_id }) => product_type_id === analysisPackagesType?.id); return { email: order.email, - partnerLocationName: order.metadata?.partner_location_name as string ?? '', - analysisPackageName: order.items?.find(item => item.product_type_id === analysisPackagesType?.id)?.title ?? '', + partnerLocationName: analysisPackageOrderItem?.metadata?.partner_location_name as string ?? '', + analysisPackageName: analysisPackageOrderItem?.title ?? '', }; } catch (error) { throw new Error(`Failed to place order, message=${error}`); @@ -105,8 +106,10 @@ export async function GET(request: Request) { const { email, partnerLocationName, analysisPackageName } = orderResult; const personName = account.name; - if (email && analysisPackageName && partnerLocationName) { + if (email && analysisPackageName) { await sendEmail({ email, analysisPackageName, personName, partnerLocationName, language }); + } else { + console.error("Missing email or analysisPackageName", orderResult); } return Response.redirect(new URL('/home/order', baseUrl)) } catch (error) { diff --git a/app/home/(user)/(dashboard)/order/[orderId]/confirmed/page.tsx b/app/home/(user)/(dashboard)/order/[orderId]/confirmed/page.tsx index 95d9e81..2ca1b55 100644 --- a/app/home/(user)/(dashboard)/order/[orderId]/confirmed/page.tsx +++ b/app/home/(user)/(dashboard)/order/[orderId]/confirmed/page.tsx @@ -3,6 +3,7 @@ import { notFound } from 'next/navigation'; import { retrieveOrder } from '~/medusa/lib/data/orders'; import { createI18nServerInstance } from '@/lib/i18n/i18n.server'; import OrderCompleted from '@/app/home/(user)/_components/order/order-completed'; +import { withI18n } from '~/lib/i18n/with-i18n'; type Props = { params: Promise<{ orderId: string }>; @@ -16,7 +17,7 @@ export async function generateMetadata() { }; } -export default async function OrderConfirmedPage(props: Props) { +async function OrderConfirmedPage(props: Props) { const params = await props.params; const order = await retrieveOrder(params.orderId).catch(() => null); @@ -26,3 +27,5 @@ export default async function OrderConfirmedPage(props: Props) { return ; } + +export default withI18n(OrderConfirmedPage); diff --git a/app/home/(user)/_components/cart/analysis-location.tsx b/app/home/(user)/_components/cart/analysis-location.tsx index 89da90c..b6128e7 100644 --- a/app/home/(user)/_components/cart/analysis-location.tsx +++ b/app/home/(user)/_components/cart/analysis-location.tsx @@ -3,8 +3,8 @@ import { toast } from 'sonner'; import { useForm } from "react-hook-form"; import { z } from "zod"; -import { updateCart } from "@lib/data/cart" -import { StoreCart } from "@medusajs/types" +import { updateLineItem } from "@lib/data/cart" +import { StoreCart, StoreCartLineItem } from "@medusajs/types" import { Form } from "@kit/ui/form"; import { Trans } from '@kit/ui/trans'; import { useTranslation } from "react-i18next"; @@ -29,7 +29,7 @@ const MOCK_LOCATIONS: { id: string, name: string }[] = [ { id: "synlab-parnu-1", name: "SYNLAB - Pärnu" }, ] -export default function AnalysisLocation({ cart }: { cart: StoreCart }) { +export default function AnalysisLocation({ cart, analysisPackages }: { cart: StoreCart, analysisPackages: StoreCartLineItem[] }) { const { t } = useTranslation('cart'); const form = useForm>({ @@ -40,12 +40,16 @@ export default function AnalysisLocation({ cart }: { cart: StoreCart }) { }); const onSubmit = async ({ locationId }: z.infer) => { - const promise = updateCart({ - metadata: { - partner_location_name: MOCK_LOCATIONS.find(({ id }) => id === locationId)?.name ?? '', - partner_location_id: locationId, - }, - }); + const promise = Promise.all(analysisPackages.map(async ({ id, quantity }) => { + await updateLineItem({ + lineId: id, + quantity, + metadata: { + partner_location_name: MOCK_LOCATIONS.find((location) => location.id === locationId)?.name ?? '', + partner_location_id: locationId, + }, + }); + })); toast.promise(promise, { success: t(`cart:items.analysisLocation.success`), diff --git a/app/home/(user)/_components/cart/index.tsx b/app/home/(user)/_components/cart/index.tsx index fc05d7c..4e0086b 100644 --- a/app/home/(user)/_components/cart/index.tsx +++ b/app/home/(user)/_components/cart/index.tsx @@ -121,7 +121,7 @@ export default function Cart({ - + )} diff --git a/app/home/(user)/_components/order/order-item.tsx b/app/home/(user)/_components/order/order-item.tsx index f938360..4cd4e7a 100644 --- a/app/home/(user)/_components/order/order-item.tsx +++ b/app/home/(user)/_components/order/order-item.tsx @@ -22,7 +22,7 @@ export default function OrderItem({ item, currencyCode }: { className="txt-medium-plus text-ui-fg-base" data-testid="product-name" > - {item.product_title} + {item.product_title}{` (${item.metadata?.partner_location_name ?? "-"})`} diff --git a/packages/features/medusa-storefront/src/lib/data/cart.ts b/packages/features/medusa-storefront/src/lib/data/cart.ts index c981ebd..6962415 100644 --- a/packages/features/medusa-storefront/src/lib/data/cart.ts +++ b/packages/features/medusa-storefront/src/lib/data/cart.ts @@ -14,6 +14,7 @@ import { } from "./cookies"; import { getRegion } from "./regions"; import { sdk } from "@lib/config"; +import { retrieveOrder } from "./orders"; /** * Retrieves a cart by its ID. If no ID is provided, it will use the cart ID from the cookies. @@ -161,9 +162,11 @@ export async function addToCart({ export async function updateLineItem({ lineId, quantity, + metadata, }: { lineId: string; quantity: number; + metadata?: Record; }) { if (!lineId) { throw new Error("Missing lineItem ID when updating line item"); @@ -180,7 +183,7 @@ export async function updateLineItem({ }; await sdk.store.cart - .updateLineItem(cartId, lineId, { quantity }, {}, headers) + .updateLineItem(cartId, lineId, { quantity, metadata }, {}, headers) .then(async () => { const cartCacheTag = await getCacheTag("carts"); revalidateTag(cartCacheTag); @@ -425,7 +428,7 @@ export async function placeOrder(cartId?: string, options: { revalidateCacheTags throw new Error("Cart is not an order"); } - return cartRes; + return retrieveOrder(cartRes.order.id); } /**