diff --git a/app/home/(user)/(dashboard)/page.tsx b/app/home/(user)/(dashboard)/page.tsx index ca9fc22..de4d375 100644 --- a/app/home/(user)/(dashboard)/page.tsx +++ b/app/home/(user)/(dashboard)/page.tsx @@ -1,7 +1,7 @@ import { redirect } from 'next/navigation'; import { toTitleCase } from '@/lib/utils'; -import { createAccountsApi } from '@/packages/features/accounts/src/server/api'; +import { createUserAnalysesApi } from '@kit/user-analyses/api'; import { getSupabaseServerClient } from '@/packages/supabase/src/clients/server-client'; import { PageBody, PageHeader } from '@kit/ui/page'; @@ -27,7 +27,7 @@ async function UserHomePage() { const client = getSupabaseServerClient(); const { account } = await loadCurrentUserAccount(); - const api = createAccountsApi(client); + const api = createUserAnalysesApi(client); const bmiThresholds = await api.fetchBmiThresholds(); if (!account) { diff --git a/app/home/[account]/page.tsx b/app/home/[account]/page.tsx index 8bc2ade..8279c92 100644 --- a/app/home/[account]/page.tsx +++ b/app/home/[account]/page.tsx @@ -2,10 +2,10 @@ import { use } from 'react'; -import { createAccountsApi } from '@/packages/features/accounts/src/server/api'; import { CompanyGuard } from '@/packages/features/team-accounts/src/components'; import { createTeamAccountsApi } from '@/packages/features/team-accounts/src/server/api'; import { getSupabaseServerClient } from '@/packages/supabase/src/clients/server-client'; +import { createUserAnalysesApi } from '@kit/user-analyses/api'; import { PageBody } from '@kit/ui/page'; @@ -35,10 +35,10 @@ function TeamAccountHomePage({ params }: TeamAccountHomePageProps) { const account = use(params).account; const client = getSupabaseServerClient(); const teamAccountsApi = createTeamAccountsApi(client); - const accountsApi = createAccountsApi(client); + const userAnalysesApi = createUserAnalysesApi(client); const teamAccount = use(teamAccountsApi.getTeamAccount(account)); const { memberParams, members } = use(teamAccountsApi.getMembers(account)); - const bmiThresholds = use(accountsApi.fetchBmiThresholds()); + const bmiThresholds = use(userAnalysesApi.fetchBmiThresholds()); const companyParams = use( teamAccountsApi.getTeamAccountParams(teamAccount.id), ); diff --git a/package.json b/package.json index 33ec639..823ccc7 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "@kit/supabase": "workspace:*", "@kit/team-accounts": "workspace:*", "@kit/ui": "workspace:*", + "@kit/user-analyses": "workspace:*", "@makerkit/data-loader-supabase-core": "^0.0.10", "@makerkit/data-loader-supabase-nextjs": "^1.2.5", "@marsidev/react-turnstile": "^1.1.0", diff --git a/packages/features/accounts/src/server/api.ts b/packages/features/accounts/src/server/api.ts index 187da61..015e0f4 100644 --- a/packages/features/accounts/src/server/api.ts +++ b/packages/features/accounts/src/server/api.ts @@ -1,11 +1,8 @@ import { SupabaseClient } from '@supabase/supabase-js'; import { Database } from '@kit/supabase/database'; -import type { UuringElement, UuringuVastus } from '@kit/shared/types/medipost-analysis'; import PersonalCode from '~/lib/utils'; -import type { AnalysisResultDetails, AnalysisResultDetailsMapped, UserAnalysis } from '../types/analysis-results'; -import type { AnalysisOrder } from '../types/analysis-orders'; import { AccountWithParams } from '../types/accounts'; /** @@ -207,89 +204,6 @@ class AccountsApi { return response.data?.customer_id; } - async getUserAnalysis( - analysisOrderId: number, - ): Promise { - const authUser = await this.client.auth.getUser(); - const { data, error: userError } = authUser; - - if (userError) { - console.error('Failed to get user', userError); - throw userError; - } - - const { user } = data; - - const { data: analysisResponse } = await this.client - .schema('medreport') - .from('analysis_responses') - .select( - `*, - elements:analysis_response_elements(analysis_name,norm_status,response_value,unit,norm_lower_included,norm_upper_included,norm_lower,norm_upper,response_time), - order:analysis_order_id(medusa_order_id, status, created_at), - summary:analysis_order_id(doctor_analysis_feedback(*))`, - ) - .eq('user_id', user.id) - .eq('analysis_order_id', analysisOrderId) - .throwOnError(); - - const responseWithElements = analysisResponse?.[0]; - if (!responseWithElements) { - return null; - } - - const feedback = responseWithElements.summary.doctor_analysis_feedback?.[0]; - - return { - ...responseWithElements, - summary: - feedback?.status === 'COMPLETED' - ? responseWithElements.summary.doctor_analysis_feedback?.[0] - : null, - }; - } - - async getUserAnalyses(): Promise { - const authUser = await this.client.auth.getUser(); - const { data, error: userError } = authUser; - - if (userError) { - console.error('Failed to get user', userError); - throw userError; - } - - const { user } = data; - - const { data: analysisResponses } = await this.client - .schema('medreport') - .from('analysis_responses') - .select('*') - .eq('user_id', user.id); - - if (!analysisResponses) { - return null; - } - - const analysisResponseIds = analysisResponses.map((r) => r.id); - - const { data: analysisResponseElements } = await this.client - .schema('medreport') - .from('analysis_response_elements') - .select('*') - .in('analysis_response_id', analysisResponseIds); - - if (!analysisResponseElements) { - return null; - } - - return analysisResponses.map((r) => ({ - ...r, - elements: analysisResponseElements.filter( - (e) => e.analysis_response_id === r.id, - ), - })); - } - async hasAccountTeamMembership(accountId?: string) { if (!accountId) { return false; @@ -307,23 +221,6 @@ class AccountsApi { return (count ?? 0) > 0; } - - async fetchBmiThresholds() { - // Fetch BMI - const { data, error } = await this.client - .schema('medreport') - .from('bmi_thresholds') - .select( - 'age_min,age_max,underweight_max,normal_min,normal_max,overweight_min,strong_min,obesity_min', - ) - .order('age_min', { ascending: true }); - - if (error) { - console.error('Error fetching BMI thresholds:', error); - throw error; - } - return data; - } } export function createAccountsApi(client: SupabaseClient) { diff --git a/packages/features/user-analyses/eslint.config.mjs b/packages/features/user-analyses/eslint.config.mjs new file mode 100644 index 0000000..97563ae --- /dev/null +++ b/packages/features/user-analyses/eslint.config.mjs @@ -0,0 +1,3 @@ +import eslintConfigBase from '@kit/eslint-config/base.js'; + +export default eslintConfigBase; diff --git a/packages/features/user-analyses/package.json b/packages/features/user-analyses/package.json new file mode 100644 index 0000000..5d40175 --- /dev/null +++ b/packages/features/user-analyses/package.json @@ -0,0 +1,33 @@ +{ + "name": "@kit/user-analyses", + "private": true, + "version": "0.1.0", + "scripts": { + "clean": "git clean -xdf .turbo node_modules", + "format": "prettier --check \"**/*.{ts,tsx}\"", + "lint": "eslint .", + "typecheck": "tsc --noEmit" + }, + "exports": { + "./api": "./src/server/api.ts", + "./types/*": "./src/types/*.ts" + }, + "dependencies": { + "nanoid": "^5.1.5" + }, + "devDependencies": { + "@kit/eslint-config": "workspace:*", + "@kit/prettier-config": "workspace:*", + "@kit/shared": "workspace:*", + "@kit/supabase": "workspace:*", + "@kit/tsconfig": "workspace:*" + }, + "prettier": "@kit/prettier-config", + "typesVersions": { + "*": { + "*": [ + "src/*" + ] + } + } +} diff --git a/packages/features/user-analyses/src/server/api.ts b/packages/features/user-analyses/src/server/api.ts new file mode 100644 index 0000000..b01047c --- /dev/null +++ b/packages/features/user-analyses/src/server/api.ts @@ -0,0 +1,307 @@ +import { SupabaseClient } from '@supabase/supabase-js'; + +import { Database } from '@kit/supabase/database'; +import type { UuringElement, UuringuVastus } from '@kit/shared/types/medipost-analysis'; + +import type { AnalysisResultDetails, AnalysisResultDetailsMapped, UserAnalysis } from '../types/analysis-results'; +import type { AnalysisOrder } from '../types/analysis-orders'; + +/** + * Class representing an API for interacting with user accounts. + * @constructor + * @param {SupabaseClient} client - The Supabase client instance. + */ +class UserAnalysesApi { + constructor(private readonly client: SupabaseClient) { } + + async getAnalysisOrder({ + medusaOrderId, + analysisOrderId, + }: { + medusaOrderId?: string; + analysisOrderId?: number; + }) { + const query = this.client + .schema('medreport') + .from('analysis_orders') + .select('*') + if (medusaOrderId) { + query.eq('medusa_order_id', medusaOrderId); + } else if (analysisOrderId) { + query.eq('id', analysisOrderId); + } else { + throw new Error('Either medusaOrderId or orderId must be provided'); + } + + const { data: order, error } = await query.single(); + if (error) { + throw new Error(`Failed to get order by medusaOrderId=${medusaOrderId} or analysisOrderId=${analysisOrderId}, message=${error.message}, data=${JSON.stringify(order)}`); + } + return order as AnalysisOrder; + } + + async getUserAnalysis( + analysisOrderId: number, + ): Promise { + const authUser = await this.client.auth.getUser(); + const { data, error: userError } = authUser; + + if (userError) { + console.error('Failed to get user', userError); + throw userError; + } + + const { user } = data; + + const analysisOrder = await this.getAnalysisOrder({ analysisOrderId }); + const orderedAnalysisElementIds = analysisOrder.analysis_element_ids ?? []; + if (orderedAnalysisElementIds.length === 0) { + console.error('No ordered analysis element ids found for analysis order id=', analysisOrderId); + return null; + } + const { data: orderedAnalysisElements, error: orderedAnalysisElementsError } = await this.client + .schema('medreport') + .from('analysis_elements') + .select('analysis_id_original,analysis_name_lab') + .in('id', orderedAnalysisElementIds); + if (orderedAnalysisElementsError) { + console.error('Failed to get ordered analysis elements for analysis order id=', analysisOrderId, orderedAnalysisElementsError); + throw orderedAnalysisElementsError; + } + + const orderedAnalysisElementOriginalIds = orderedAnalysisElements.map(({ analysis_id_original }) => analysis_id_original); + if (orderedAnalysisElementOriginalIds.length === 0) { + console.error('No ordered analysis element original ids found for analysis order id=', analysisOrderId); + return null; + } + + const { data: analysisResponse } = await this.client + .schema('medreport') + .from('analysis_responses') + .select( + `*, + elements:analysis_response_elements(analysis_name,norm_status,response_value,unit,norm_lower_included,norm_upper_included,norm_lower,norm_upper,response_time,status,analysis_element_original_id,original_response_element,response_value_is_negative), + summary:analysis_order_id(doctor_analysis_feedback(*))`, + ) + .eq('user_id', user.id) + .eq('analysis_order_id', analysisOrderId) + .throwOnError(); + + const responseWithElements = analysisResponse?.[0] as AnalysisResultDetails | null; + if (!responseWithElements) { + return null; + } + + const analysisResponseElements = responseWithElements.elements; + + const feedback = responseWithElements.summary?.doctor_analysis_feedback?.[0]; + + const mappedOrderedAnalysisElements = orderedAnalysisElements.map(({ analysis_id_original, analysis_name_lab }) => { + return this.getOrderedAnalysisElements({ + analysisIdOriginal: analysis_id_original, + analysisNameLab: analysis_name_lab, + analysisResponseElements, + }); + }).sort((a, b) => a.analysisName.localeCompare(b.analysisName)); + const nestedAnalysisElementIds = mappedOrderedAnalysisElements.map(({ results }) => results?.nestedElements.map(({ analysisElementOriginalId }) => analysisElementOriginalId)).flat(); + if (nestedAnalysisElementIds.length > 0) { + const { data: nestedAnalysisElements, error: nestedAnalysisElementsError } = await this.client + .schema('medreport') + .from('analysis_elements') + .select('*') + .in('id', nestedAnalysisElementIds); + console.info('analysisResponse nestedAnalysisElementIds', nestedAnalysisElementIds) + if (!nestedAnalysisElementsError && nestedAnalysisElements) { + for (const mappedOrderedAnalysisElement of mappedOrderedAnalysisElements) { + const { results } = mappedOrderedAnalysisElement; + if (!results) { + continue; + } + for (const nestedElement of results.nestedElements) { + const { analysisElementOriginalId } = nestedElement; + const nestedAnalysisElement = nestedAnalysisElements.find(({ id }) => id === analysisElementOriginalId); + if (!nestedAnalysisElement) { + continue; + } + results.nestedElements.push({ + ...nestedAnalysisElement, + analysisElementOriginalId, + analysisName: nestedAnalysisElement.analysis_name_lab, + }); + } + } + + mappedOrderedAnalysisElements.forEach(({ results }) => { + results?.nestedElements.forEach(({ analysisElementOriginalId }) => { + const nestedAnalysisElement = nestedAnalysisElements.find(({ id }) => id === analysisElementOriginalId); + if (nestedAnalysisElement) { + results?.nestedElements.push({ + ...nestedAnalysisElement, + analysisElementOriginalId, + analysisName: nestedAnalysisElement.analysis_name_lab, + }); + } + }); + }); + } + } + + return { + id: analysisOrderId, + order: { + status: analysisOrder.status, + medusaOrderId: analysisOrder.medusa_order_id, + createdAt: new Date(analysisOrder.created_at), + }, + orderedAnalysisElementIds, + orderedAnalysisElements: mappedOrderedAnalysisElements, + summary: + feedback?.status === 'COMPLETED' + ? (responseWithElements.summary?.doctor_analysis_feedback?.[0] ?? null) + : null, + }; + } + + getOrderedAnalysisElements({ + analysisIdOriginal, + analysisNameLab, + analysisResponseElements, + }: { + analysisIdOriginal: string; + analysisNameLab: string; + analysisResponseElements: AnalysisResultDetails['elements']; + }) { + const elementResponse = analysisResponseElements.find((element) => element.analysis_element_original_id === analysisIdOriginal); + if (!elementResponse) { + return { + analysisIdOriginal, + isWaitingForResults: true, + analysisName: analysisNameLab, + }; + } + const labComment = elementResponse.original_response_element?.UuringuKommentaar; + return { + analysisIdOriginal, + isWaitingForResults: false, + analysisName: analysisNameLab, + results: { + nestedElements: (() => { + const nestedElements = elementResponse.original_response_element?.UuringuElement as UuringElement[] | undefined; + if (!nestedElements) { + return []; + } + return nestedElements.map((element) => { + const elementVastus = element.UuringuVastus as UuringuVastus | undefined; + return { + status: element.UuringOlek, + unit: element.Mootyhik, + normLower: elementVastus?.NormAlum?.['#text'], + normUpper: elementVastus?.NormYlem?.['#text'], + normStatus: elementVastus?.NormiStaatus, + responseTime: elementVastus?.VastuseAeg, + responseValue: elementVastus?.VastuseVaartus, + responseValueIsNegative: elementVastus?.VastuseVaartus === 'Negatiivne', + normLowerIncluded: elementVastus?.NormAlum?.['@_kaasaarvatud'] === 'JAH', + normUpperIncluded: elementVastus?.NormYlem?.['@_kaasaarvatud'] === 'JAH', + analysisElementOriginalId: element.UuringId, + }; + }); + })(), + labComment, + //originalResponseElement: elementResponse.original_response_element ?? null, + unit: elementResponse.unit, + normLower: elementResponse.norm_lower, + normUpper: elementResponse.norm_upper, + normStatus: elementResponse.norm_status, + responseTime: elementResponse.response_time, + responseValue: elementResponse.response_value, + responseValueIsNegative: elementResponse.response_value_is_negative === true, + normLowerIncluded: elementResponse.norm_lower_included, + normUpperIncluded: elementResponse.norm_upper_included, + status: elementResponse.status, + analysisElementOriginalId: elementResponse.analysis_element_original_id, + } + }; + } + + // @TODO unused currently + async getUserAnalyses(): Promise { + const authUser = await this.client.auth.getUser(); + const { data, error: userError } = authUser; + + if (userError) { + console.error('Failed to get user', userError); + throw userError; + } + + const { user } = data; + + const { data: analysisResponses } = await this.client + .schema('medreport') + .from('analysis_responses') + .select('*') + .eq('user_id', user.id); + + if (!analysisResponses) { + return null; + } + + const analysisResponseIds = analysisResponses.map((r) => r.id); + + const { data: analysisResponseElements } = await this.client + .schema('medreport') + .from('analysis_response_elements') + .select('*') + .in('analysis_response_id', analysisResponseIds); + + if (!analysisResponseElements) { + return null; + } + + return analysisResponses.map((r) => ({ + ...r, + elements: analysisResponseElements.filter( + (e) => e.analysis_response_id === r.id, + ), + })); + } + + async hasAccountTeamMembership(accountId?: string) { + if (!accountId) { + return false; + } + + const { count, error } = await this.client + .schema('medreport') + .from('accounts_memberships') + .select('account_id', { count: 'exact', head: true }) + .eq('account_id', accountId); + + if (error) { + throw error; + } + + return (count ?? 0) > 0; + } + + async fetchBmiThresholds() { + // Fetch BMI + const { data, error } = await this.client + .schema('medreport') + .from('bmi_thresholds') + .select( + 'age_min,age_max,underweight_max,normal_min,normal_max,overweight_min,strong_min,obesity_min', + ) + .order('age_min', { ascending: true }); + + if (error) { + console.error('Error fetching BMI thresholds:', error); + throw error; + } + return data; + } +} + +export function createUserAnalysesApi(client: SupabaseClient) { + return new UserAnalysesApi(client); +} diff --git a/packages/features/user-analyses/src/types/analysis-orders.ts b/packages/features/user-analyses/src/types/analysis-orders.ts new file mode 100644 index 0000000..4ef4027 --- /dev/null +++ b/packages/features/user-analyses/src/types/analysis-orders.ts @@ -0,0 +1,3 @@ +import { Tables } from '@kit/supabase/database'; + +export type AnalysisOrder = Tables<{ schema: 'medreport' }, 'analysis_orders'>; diff --git a/packages/features/user-analyses/src/types/analysis-results.ts b/packages/features/user-analyses/src/types/analysis-results.ts new file mode 100644 index 0000000..64ddb83 --- /dev/null +++ b/packages/features/user-analyses/src/types/analysis-results.ts @@ -0,0 +1,138 @@ +import * as z from 'zod'; + +import { Database } from '@kit/supabase/database'; + +export type UserAnalysisElement = + Database['medreport']['Tables']['analysis_response_elements']['Row']; +export type UserAnalysisResponse = + Database['medreport']['Tables']['analysis_responses']['Row'] & { + elements: UserAnalysisElement[]; + }; +export type UserAnalysis = UserAnalysisResponse[]; + +const ElementSchema = z.object({ + unit: z.string(), + norm_lower: z.number(), + norm_upper: z.number(), + norm_status: z.number(), + analysis_name: z.string(), + response_time: z.string(), + response_value: z.number(), + response_value_is_negative: z.boolean(), + norm_lower_included: z.boolean(), + norm_upper_included: z.boolean(), + status: z.string(), + analysis_element_original_id: z.string(), + original_response_element: z.object({ + + }), +}); + +const OrderSchema = z.object({ + status: z.string(), + medusa_order_id: z.string(), + created_at: z.coerce.date(), +}); + +const DoctorAnalysisFeedbackSchema = z.object({ + id: z.number(), + status: z.string(), + user_id: z.string(), + created_at: z.coerce.date(), + created_by: z.string(), +}); + +const SummarySchema = z.object({ + id: z.number(), + value: z.string(), + status: z.string(), + user_id: z.string(), + created_at: z.coerce.date(), + created_by: z.string(), + updated_at: z.coerce.date().nullable(), + updated_by: z.string(), + doctor_user_id: z.string().nullable(), + analysis_order_id: z.number(), + doctor_analysis_feedback: z.array(DoctorAnalysisFeedbackSchema), +}); + +export const AnalysisResultDetailsSchema = z.object({ + id: z.number(), + analysis_order_id: z.number(), + order_number: z.string(), + order_status: z.string(), + user_id: z.string(), + created_at: z.coerce.date(), + updated_at: z.coerce.date().nullable(), + elements: z.array(ElementSchema), + order: OrderSchema, + summary: SummarySchema.nullable(), +}); +export type AnalysisResultDetails = z.infer; + +export type AnalysisResultDetailsElementResults = { + unit: string | null; + normLower: number | null; + normUpper: number | null; + normStatus: number | null; + responseTime: string | null; + responseValue: number | null; + responseValueIsNegative: boolean | null; + normLowerIncluded: boolean; + normUpperIncluded: boolean; + status: string; + analysisElementOriginalId: string; + nestedElements: { + analysisElementOriginalId: string; + normLower?: number | null; + normLowerIncluded: boolean; + normStatus: number; + normUpper?: number | null; + normUpperIncluded: boolean; + responseTime: string; + responseValue: number; + status: number; + unit: string; + }[]; + labComment?: string | null; +}; + +export type AnalysisResultDetailsElement = { + analysisIdOriginal: string; + isWaitingForResults: boolean; + analysisName: string; + results: AnalysisResultDetailsElementResults; +}; + +export type AnalysisResultDetailsMapped = { + id: number; + order: { + status: string; + medusaOrderId: string; + createdAt: Date | string; + }; + elements: { + id: string; + unit: string; + norm_lower: number; + norm_upper: number; + norm_status: number; + analysis_name: string; + response_time: string; + response_value: number; + norm_lower_included: boolean; + norm_upper_included: boolean; + status: string; + analysis_element_original_id: string; + }[]; + orderedAnalysisElementIds: number[]; + orderedAnalysisElements: AnalysisResultDetailsElement[]; + summary: { + id: number; + status: string; + user_id: string; + created_at: Date; + created_by: string; + value?: string; + } | null; +}; diff --git a/packages/features/user-analyses/tsconfig.json b/packages/features/user-analyses/tsconfig.json new file mode 100644 index 0000000..8d5bae9 --- /dev/null +++ b/packages/features/user-analyses/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "@kit/tsconfig/base.json", + "compilerOptions": { + "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json", + "paths": { + "~/lib/utils": ["../../../lib/utils.ts"] + } + }, + "include": ["*.ts", "*.tsx", "src"], + "exclude": ["node_modules"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 77d0440..041d098 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -71,6 +71,9 @@ importers: '@kit/ui': specifier: workspace:* version: link:packages/ui + '@kit/user-analyses': + specifier: workspace:* + version: link:packages/features/user-analyses '@makerkit/data-loader-supabase-core': specifier: ^0.0.10 version: 0.0.10(@supabase/postgrest-js@1.19.4)(@supabase/supabase-js@2.49.4) @@ -478,10 +481,10 @@ importers: dependencies: '@keystatic/core': specifier: 0.5.47 - version: 0.5.47(next@15.5.2(@babel/core@7.28.3)(@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) + version: 0.5.47(next@15.3.2(@babel/core@7.28.3)(@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.5.2(@babel/core@7.28.3)(@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.5.2(@babel/core@7.28.3)(@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) + version: 5.0.4(@keystatic/core@0.5.47(next@15.3.2(@babel/core@7.28.3)(@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.3.2(@babel/core@7.28.3)(@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.4(@types/react@19.1.4)(react@19.1.0) @@ -1073,6 +1076,28 @@ importers: specifier: ^2.0.3 version: 2.0.7(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + packages/features/user-analyses: + dependencies: + nanoid: + specifier: ^5.1.5 + version: 5.1.5 + devDependencies: + '@kit/eslint-config': + specifier: workspace:* + version: link:../../../tooling/eslint + '@kit/prettier-config': + specifier: workspace:* + version: link:../../../tooling/prettier + '@kit/shared': + specifier: workspace:* + version: link:../../shared + '@kit/supabase': + specifier: workspace:* + version: link:../../supabase + '@kit/tsconfig': + specifier: workspace:* + version: link:../../../tooling/typescript + packages/i18n: dependencies: i18next: @@ -1272,7 +1297,7 @@ importers: dependencies: '@sentry/nextjs': specifier: ^9.19.0 - version: 9.46.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(next@15.5.2(@babel/core@7.28.3)(@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.101.3) + version: 9.46.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(next@15.3.2(@babel/core@7.28.3)(@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.101.3) import-in-the-middle: specifier: 1.13.2 version: 1.13.2 @@ -11457,7 +11482,7 @@ snapshots: '@juggle/resize-observer@3.4.0': {} - '@keystar/ui@0.7.19(next@15.5.2(@babel/core@7.28.3)(@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)': + '@keystar/ui@0.7.19(next@15.3.2(@babel/core@7.28.3)(@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 @@ -11550,18 +11575,18 @@ snapshots: react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - next: 15.5.2(@babel/core@7.28.3)(@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: 15.3.2(@babel/core@7.28.3)(@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.5.2(@babel/core@7.28.3)(@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/core@0.5.47(next@15.3.2(@babel/core@7.28.3)(@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.5.2(@babel/core@7.28.3)(@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) + '@keystar/ui': 0.7.19(next@15.3.2(@babel/core@7.28.3)(@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) @@ -11632,13 +11657,13 @@ snapshots: - next - supports-color - '@keystatic/next@5.0.4(@keystatic/core@0.5.47(next@15.5.2(@babel/core@7.28.3)(@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.5.2(@babel/core@7.28.3)(@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@5.0.4(@keystatic/core@0.5.47(next@15.3.2(@babel/core@7.28.3)(@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.3.2(@babel/core@7.28.3)(@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.5.2(@babel/core@7.28.3)(@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/core': 0.5.47(next@15.3.2(@babel/core@7.28.3)(@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.5.2(@babel/core@7.28.3)(@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: 15.3.2(@babel/core@7.28.3)(@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 @@ -17232,7 +17257,7 @@ snapshots: '@sentry/core@9.46.0': {} - '@sentry/nextjs@9.46.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(next@15.5.2(@babel/core@7.28.3)(@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.101.3)': + '@sentry/nextjs@9.46.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(next@15.3.2(@babel/core@7.28.3)(@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.101.3)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/semantic-conventions': 1.34.0 @@ -17245,7 +17270,7 @@ snapshots: '@sentry/vercel-edge': 9.46.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0)) '@sentry/webpack-plugin': 3.5.0(webpack@5.101.3) chalk: 3.0.0 - next: 15.5.2(@babel/core@7.28.3)(@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: 15.3.2(@babel/core@7.28.3)(@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 @@ -19173,8 +19198,8 @@ snapshots: '@typescript-eslint/parser': 8.33.1(eslint@8.10.0)(typescript@5.9.2) 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.9.2))(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.9.2))(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.9.2))(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.9.2))(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) @@ -19193,8 +19218,8 @@ snapshots: '@typescript-eslint/parser': 8.33.1(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) eslint: 9.34.0(jiti@2.5.1) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0)(eslint@9.34.0(jiti@2.5.1)) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.34.0(jiti@2.5.1)) eslint-plugin-react: 7.37.5(eslint@9.34.0(jiti@2.5.1)) eslint-plugin-react-hooks: 5.2.0(eslint@9.34.0(jiti@2.5.1)) @@ -19219,22 +19244,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.9.2))(eslint@8.10.0) - transitivePeerDependencies: - - supports-color - - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0)(eslint@9.34.0(jiti@2.5.1)): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.1 @@ -19245,62 +19255,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.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.9.2))(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.9.2))(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.9.2))(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.9.2))(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.9.2))(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.9.2))(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.9.2) 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.9.2))(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.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.34.0(jiti@2.5.1)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.33.1(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(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.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.33.1(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) eslint: 9.34.0(jiti@2.5.1) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0)(eslint@9.34.0(jiti@2.5.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)): - 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.34.0(jiti@2.5.1) - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.33.1(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.34.0(jiti@2.5.1)) - 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.34.0(jiti@2.5.1))(typescript@5.9.2) - 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.9.2))(eslint@8.10.0): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.9.2))(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.9.2))(eslint@8.10.0))(eslint@8.10.0))(eslint@8.10.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -19311,7 +19307,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.9.2))(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.9.2))(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.9.2))(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 @@ -19329,6 +19325,35 @@ snapshots: - eslint-import-resolver-webpack - supports-color + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)): + 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.34.0(jiti@2.5.1) + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.33.1(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(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.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)))(eslint@9.34.0(jiti@2.5.1)) + 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.34.0(jiti@2.5.1))(typescript@5.9.2) + 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 @@ -21269,31 +21294,6 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@15.5.2(@babel/core@7.28.3)(@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.5.2 - '@swc/helpers': 0.5.15 - caniuse-lite: 1.0.30001723 - postcss: 8.4.31 - react: 19.1.0 - react-dom: 19.1.0(react@19.1.0) - styled-jsx: 5.1.6(@babel/core@7.28.3)(babel-plugin-macros@3.1.0)(react@19.1.0) - optionalDependencies: - '@next/swc-darwin-arm64': 15.5.2 - '@next/swc-darwin-x64': 15.5.2 - '@next/swc-linux-arm64-gnu': 15.5.2 - '@next/swc-linux-arm64-musl': 15.5.2 - '@next/swc-linux-x64-gnu': 15.5.2 - '@next/swc-linux-x64-musl': 15.5.2 - '@next/swc-win32-arm64-msvc': 15.5.2 - '@next/swc-win32-x64-msvc': 15.5.2 - '@opentelemetry/api': 1.9.0 - babel-plugin-react-compiler: 19.1.0-rc.2 - sharp: 0.34.3 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - no-case@3.0.4: dependencies: lower-case: 2.0.2