From a188af1f884da4338a39ffc0ff1e4bea11c7dbc8 Mon Sep 17 00:00:00 2001 From: Corentin Thomasset Date: Fri, 4 Jul 2025 22:55:42 +0200 Subject: [PATCH] chore(lint): enabled type-aware linting (#398) --- apps/papra-client/eslint.config.js | 5 + .../src/modules/demo/demo-api-mock.models.ts | 4 +- .../src/modules/ui/components/alert.tsx | 4 +- .../src/modules/ui/components/button.tsx | 4 +- .../src/modules/ui/components/combobox.tsx | 4 +- .../src/modules/ui/components/dialog.tsx | 4 +- .../modules/ui/components/dropdown-menu.tsx | 24 +- .../modules/ui/components/number-field.tsx | 8 +- .../src/modules/ui/components/select.tsx | 4 +- .../src/modules/ui/components/sheet.tsx | 8 +- .../src/modules/ui/components/tabs.tsx | 12 +- .../src/modules/ui/components/textfield.tsx | 16 +- .../modules/ui/components/toggle-group.tsx | 8 +- .../src/modules/ui/components/toggle.tsx | 10 +- .../src/modules/ui/components/tooltip.tsx | 4 +- .../plugins/i18n-types/i18n-types.services.ts | 5 +- apps/papra-server/eslint.config.js | 8 + .../modules/api-keys/api-keys.constants.ts | 5 + .../modules/api-keys/api-keys.middlewares.ts | 8 +- .../modules/api-keys/api-keys.repository.ts | 11 + .../src/modules/api-keys/api-keys.routes.ts | 8 +- .../src/modules/api-keys/api-keys.schemas.ts | 4 + .../src/modules/api-keys/api-keys.tables.ts | 3 +- .../api-keys/api-keys.usecases.test.ts | 2 +- .../src/modules/app/auth/auth.models.ts | 3 +- .../src/modules/app/auth/auth.routes.ts | 7 +- .../src/modules/app/auth/auth.services.ts | 4 +- .../app/database/database.test-utils.ts | 2 +- .../health-check/health-check.repository.ts | 2 +- .../app/middlewares/errors.middleware.test.ts | 17 +- .../middlewares/timeout.middleware.test.ts | 5 +- .../src/modules/app/server.routes.test.ts | 2 +- .../src/modules/config/config.routes.ts | 2 +- .../src/modules/documents/documents.models.ts | 3 +- .../modules/documents/documents.repository.ts | 54 +- .../src/modules/documents/documents.routes.ts | 6 +- .../modules/documents/documents.usecases.ts | 51 +- .../storage/documents.storage.services.ts | 3 +- .../storage/drivers/b2/b2.storage-driver.ts | 14 +- .../drivers/fs/fs.storage-driver.test.ts | 2 +- .../memory/memory.storage-driver.test.ts | 2 +- .../src/modules/emails/emails.services.ts | 6 +- .../ingestion-folder.models.ts | 3 +- .../ingestion-folders.services.ts | 6 +- .../ingestion-folders.usecases.test.ts | 12 +- .../ingestion-folders.usecases.ts | 15 +- .../intake-emails/intake-emails.models.ts | 16 +- .../intake-emails/intake-emails.repository.ts | 24 +- .../intake-emails/intake-emails.routes.ts | 3 +- .../intake-emails/intake-emails.services.ts | 6 +- .../intake-emails/intake-emails.usecases.ts | 4 +- .../modules/invitations/invitations.routes.ts | 23 +- .../organizations/organization.schemas.ts | 3 +- .../organizations/organizations.constants.ts | 3 + .../organizations.repository.models.ts | 2 +- .../organizations/organizations.repository.ts | 47 +- .../organizations/organizations.routes.ts | 2 +- .../organizations/organizations.table.ts | 4 +- .../organizations.usecases.test.ts | 2 +- .../organizations/organizations.usecases.ts | 3 +- .../modules/plans/plans.repository.test.ts | 2 +- .../src/modules/roles/roles.models.test.ts | 55 - .../src/modules/roles/roles.models.ts | 15 - .../modules/shared/async/defer.test-utils.ts | 2 +- .../src/modules/shared/async/defer.ts | 2 +- .../src/modules/shared/errors/errors.test.ts | 1 + .../src/modules/shared/errors/errors.ts | 4 +- .../src/modules/shared/fs/fs.services.ts | 2 +- .../shared/logger/logger.middleware.ts | 3 +- apps/papra-server/src/modules/shared/path.ts | 2 +- .../src/modules/shared/random/ids.ts | 2 +- .../modules/shared/streams/readable-stream.ts | 2 +- .../src/modules/shared/utils.test.ts | 27 +- apps/papra-server/src/modules/shared/utils.ts | 8 + .../modules/shared/validation/validation.ts | 4 +- .../subscriptions.models.test.ts | 11 +- .../subscriptions/subscriptions.models.ts | 10 + .../subscriptions/subscriptions.routes.ts | 8 +- .../subscriptions/subscriptions.services.ts | 3 +- .../subscriptions/subscriptions.usecases.ts | 5 +- .../tagging-rules/tagging-rules.models.ts | 4 +- .../tagging-rules/tagging-rules.repository.ts | 6 + .../tagging-rules.usecases.test.ts | 16 + .../tagging-rules/tagging-rules.usecases.ts | 2 +- .../src/modules/tags/tags.repository.test.ts | 6 + .../src/modules/tasks/task-scheduler.ts | 4 +- .../src/modules/tracking/tracking.services.ts | 4 +- .../src/modules/users/users.routes.ts | 2 +- .../modules/webhooks/webhook.repository.ts | 12 +- .../src/modules/webhooks/webhook.usecases.ts | 4 +- .../src/scripts/commons/run-script.ts | 2 +- .../src/scripts/migrate-up.script.ts | 2 +- .../src/scripts/send-intake-email.script.ts | 2 +- apps/papra-server/tsconfig.json | 1 + pnpm-lock.yaml | 2037 ++++++++++++----- pnpm-workspace.yaml | 4 +- 96 files changed, 1918 insertions(+), 894 deletions(-) create mode 100644 apps/papra-server/src/modules/api-keys/api-keys.schemas.ts delete mode 100644 apps/papra-server/src/modules/roles/roles.models.test.ts delete mode 100644 apps/papra-server/src/modules/roles/roles.models.ts diff --git a/apps/papra-client/eslint.config.js b/apps/papra-client/eslint.config.js index e0175da..d17dda4 100644 --- a/apps/papra-client/eslint.config.js +++ b/apps/papra-client/eslint.config.js @@ -5,6 +5,11 @@ export default antfu({ semi: true, }, + ignores: [ + // Generated file + 'src/modules/i18n/locales.types.ts', + ], + rules: { // To allow export on top of files 'ts/no-use-before-define': ['error', { allowNamedExports: true, functions: false }], diff --git a/apps/papra-client/src/modules/demo/demo-api-mock.models.ts b/apps/papra-client/src/modules/demo/demo-api-mock.models.ts index 0da03ed..acf424c 100644 --- a/apps/papra-client/src/modules/demo/demo-api-mock.models.ts +++ b/apps/papra-client/src/modules/demo/demo-api-mock.models.ts @@ -2,8 +2,8 @@ import type { HttpClientOptions, ResponseType } from '../shared/http/http-client'; import { joinUrlPaths } from '@corentinth/chisels'; -type ExtractRouteParams = - Path extends `${infer _Start}:${infer Param}/${infer Rest}` +type ExtractRouteParams + = Path extends `${infer _Start}:${infer Param}/${infer Rest}` ? { [k in Param | keyof ExtractRouteParams<`/${Rest}`>]: string } : Path extends `${infer _Start}:${infer Param}` ? { [k in Param]: string } diff --git a/apps/papra-client/src/modules/ui/components/alert.tsx b/apps/papra-client/src/modules/ui/components/alert.tsx index aba085d..1134c84 100644 --- a/apps/papra-client/src/modules/ui/components/alert.tsx +++ b/apps/papra-client/src/modules/ui/components/alert.tsx @@ -24,8 +24,8 @@ export const alertVariants = cva( }, ); -type alertProps = AlertRootProps & - VariantProps & { +type alertProps = AlertRootProps + & VariantProps & { class?: string; }; diff --git a/apps/papra-client/src/modules/ui/components/button.tsx b/apps/papra-client/src/modules/ui/components/button.tsx index 7f82d7e..ddca853 100644 --- a/apps/papra-client/src/modules/ui/components/button.tsx +++ b/apps/papra-client/src/modules/ui/components/button.tsx @@ -33,8 +33,8 @@ export const buttonVariants = cva( }, ); -type buttonProps = ButtonRootProps & - VariantProps & { +type buttonProps = ButtonRootProps + & VariantProps & { class?: string; isLoading?: boolean; children?: JSX.Element; diff --git a/apps/papra-client/src/modules/ui/components/combobox.tsx b/apps/papra-client/src/modules/ui/components/combobox.tsx index 39a30b2..ecef69b 100644 --- a/apps/papra-client/src/modules/ui/components/combobox.tsx +++ b/apps/papra-client/src/modules/ui/components/combobox.tsx @@ -88,8 +88,8 @@ export function ComboboxTrigger(props: Poly ); } -type comboboxContentProps = - ComboboxContentProps & { +type comboboxContentProps + = ComboboxContentProps & { class?: string; }; diff --git a/apps/papra-client/src/modules/ui/components/dialog.tsx b/apps/papra-client/src/modules/ui/components/dialog.tsx index 7dd6a75..84019ff 100644 --- a/apps/papra-client/src/modules/ui/components/dialog.tsx +++ b/apps/papra-client/src/modules/ui/components/dialog.tsx @@ -77,8 +77,8 @@ export function DialogTitle(props: PolymorphicP ); } -type dialogDescriptionProps = - DialogDescriptionProps & { +type dialogDescriptionProps + = DialogDescriptionProps & { class?: string; }; diff --git a/apps/papra-client/src/modules/ui/components/dropdown-menu.tsx b/apps/papra-client/src/modules/ui/components/dropdown-menu.tsx index 8f7c947..73ace4f 100644 --- a/apps/papra-client/src/modules/ui/components/dropdown-menu.tsx +++ b/apps/papra-client/src/modules/ui/components/dropdown-menu.tsx @@ -26,8 +26,8 @@ export function DropdownMenu(props: DropdownMenuRootProps) { return ; } -type dropdownMenuContentProps = - DropdownMenuContentProps & { +type dropdownMenuContentProps + = DropdownMenuContentProps & { class?: string; }; @@ -49,8 +49,8 @@ export function DropdownMenuContent(props: Pol ); } -type dropdownMenuItemProps = - DropdownMenuItemProps & { +type dropdownMenuItemProps + = DropdownMenuItemProps & { class?: string; inset?: boolean; }; @@ -73,8 +73,8 @@ export function DropdownMenuItem(props: Polymo ); } -type dropdownMenuGroupLabelProps = - DropdownMenuGroupLabelProps & { +type dropdownMenuGroupLabelProps + = DropdownMenuGroupLabelProps & { class?: string; }; @@ -92,8 +92,8 @@ export function DropdownMenuGroupLabel(props: ); } -type dropdownMenuItemLabelProps = - DropdownMenuItemLabelProps & { +type dropdownMenuItemLabelProps + = DropdownMenuItemLabelProps & { class?: string; }; @@ -111,8 +111,8 @@ export function DropdownMenuItemLabel(props: P ); } -type dropdownMenuSeparatorProps = - DropdownMenuSeparatorProps & { +type dropdownMenuSeparatorProps + = DropdownMenuSeparatorProps & { class?: string; }; @@ -178,8 +178,8 @@ export function DropdownMenuSubTrigger(props: ); } -type dropdownMenuSubContentProps = - DropdownMenuSubTriggerProps & { +type dropdownMenuSubContentProps + = DropdownMenuSubTriggerProps & { class?: string; }; diff --git a/apps/papra-client/src/modules/ui/components/number-field.tsx b/apps/papra-client/src/modules/ui/components/number-field.tsx index 854ba52..c0abd57 100644 --- a/apps/papra-client/src/modules/ui/components/number-field.tsx +++ b/apps/papra-client/src/modules/ui/components/number-field.tsx @@ -60,8 +60,8 @@ export function NumberFieldErrorMessage(props: ); } -type numberFieldProps = - NumberFieldRootProps & { +type numberFieldProps + = NumberFieldRootProps & { class?: string; }; @@ -87,8 +87,8 @@ export function NumberFieldGroup(props: ComponentProps<'div'>) { ); } -type numberFieldInputProps = - NumberFieldInputProps & { +type numberFieldInputProps + = NumberFieldInputProps & { class?: string; }; diff --git a/apps/papra-client/src/modules/ui/components/select.tsx b/apps/papra-client/src/modules/ui/components/select.tsx index 3aa0ff8..e51d2ad 100644 --- a/apps/papra-client/src/modules/ui/components/select.tsx +++ b/apps/papra-client/src/modules/ui/components/select.tsx @@ -55,8 +55,8 @@ export function SelectTrigger(props: Polymo ); } -type selectContentProps = - SelectContentProps & { +type selectContentProps + = SelectContentProps & { class?: string; }; diff --git a/apps/papra-client/src/modules/ui/components/sheet.tsx b/apps/papra-client/src/modules/ui/components/sheet.tsx index 4c9456f..26653c1 100644 --- a/apps/papra-client/src/modules/ui/components/sheet.tsx +++ b/apps/papra-client/src/modules/ui/components/sheet.tsx @@ -32,8 +32,8 @@ export const sheetVariants = cva( ); type sheetContentProps = ParentProps< - DialogContentProps & - VariantProps & { + DialogContentProps + & VariantProps & { class?: string; } >; @@ -96,8 +96,8 @@ export function SheetTitle(props: PolymorphicPr ); } -type sheetDescriptionProps = - DialogDescriptionProps & { +type sheetDescriptionProps + = DialogDescriptionProps & { class?: string; }; diff --git a/apps/papra-client/src/modules/ui/components/tabs.tsx b/apps/papra-client/src/modules/ui/components/tabs.tsx index 1ab578e..b38d53c 100644 --- a/apps/papra-client/src/modules/ui/components/tabs.tsx +++ b/apps/papra-client/src/modules/ui/components/tabs.tsx @@ -46,8 +46,8 @@ export function TabsList(props: PolymorphicPro ); } -type tabsContentProps = - TabsContentProps & { +type tabsContentProps + = TabsContentProps & { class?: string; }; @@ -65,8 +65,8 @@ export function TabsContent(props: Polymorphic ); } -type tabsTriggerProps = - TabsTriggerProps & { +type tabsTriggerProps + = TabsTriggerProps & { class?: string; }; @@ -100,8 +100,8 @@ const tabsIndicatorVariants = cva( ); type tabsIndicatorProps = VoidProps< - TabsIndicatorProps & - VariantProps & { + TabsIndicatorProps + & VariantProps & { class?: string; } >; diff --git a/apps/papra-client/src/modules/ui/components/textfield.tsx b/apps/papra-client/src/modules/ui/components/textfield.tsx index 06ef430..8148a35 100644 --- a/apps/papra-client/src/modules/ui/components/textfield.tsx +++ b/apps/papra-client/src/modules/ui/components/textfield.tsx @@ -12,8 +12,8 @@ import { cva } from 'class-variance-authority'; import { splitProps } from 'solid-js'; import { cn } from '@/modules/shared/style/cn'; -type textFieldProps = - TextFieldRootProps & { +type textFieldProps + = TextFieldRootProps & { class?: string; }; @@ -43,8 +43,8 @@ export const textfieldLabel = cva( }, ); -type textFieldLabelProps = - TextFieldLabelProps & { +type textFieldLabelProps + = TextFieldLabelProps & { class?: string; }; @@ -59,8 +59,8 @@ export function TextFieldLabel(props: Polymo ); } -type textFieldErrorMessageProps = - TextFieldErrorMessageProps & { +type textFieldErrorMessageProps + = TextFieldErrorMessageProps & { class?: string; }; @@ -77,8 +77,8 @@ export function TextFieldErrorMessage(props: P ); } -type textFieldDescriptionProps = - TextFieldDescriptionProps & { +type textFieldDescriptionProps + = TextFieldDescriptionProps & { class?: string; }; diff --git a/apps/papra-client/src/modules/ui/components/toggle-group.tsx b/apps/papra-client/src/modules/ui/components/toggle-group.tsx index 36ac092..c8e1ed6 100644 --- a/apps/papra-client/src/modules/ui/components/toggle-group.tsx +++ b/apps/papra-client/src/modules/ui/components/toggle-group.tsx @@ -25,8 +25,8 @@ function useToggleGroup() { } type toggleGroupProps = ParentProps< - ToggleGroupRootProps & - VariantProps & { + ToggleGroupRootProps + & VariantProps & { class?: string; } >; @@ -56,8 +56,8 @@ export function ToggleGroup(props: Polymorphic ); } -type toggleGroupItemProps = - ToggleGroupItemProps & { +type toggleGroupItemProps + = ToggleGroupItemProps & { class?: string; }; diff --git a/apps/papra-client/src/modules/ui/components/toggle.tsx b/apps/papra-client/src/modules/ui/components/toggle.tsx index 652580a..0a69a45 100644 --- a/apps/papra-client/src/modules/ui/components/toggle.tsx +++ b/apps/papra-client/src/modules/ui/components/toggle.tsx @@ -28,11 +28,11 @@ export const toggleVariants = cva( }, ); -type toggleButtonProps = - ToggleButtonRootProps & - VariantProps & { - class?: string; - }; +type toggleButtonProps + = ToggleButtonRootProps + & VariantProps & { + class?: string; + }; export function ToggleButton(props: PolymorphicProps>) { const [local, rest] = splitProps(props as toggleButtonProps, [ diff --git a/apps/papra-client/src/modules/ui/components/tooltip.tsx b/apps/papra-client/src/modules/ui/components/tooltip.tsx index b93045a..16c8dbc 100644 --- a/apps/papra-client/src/modules/ui/components/tooltip.tsx +++ b/apps/papra-client/src/modules/ui/components/tooltip.tsx @@ -22,8 +22,8 @@ export function Tooltip(props: TooltipRootProps) { return ; } -type tooltipContentProps = - TooltipContentProps & { +type tooltipContentProps + = TooltipContentProps & { class?: string; }; diff --git a/apps/papra-client/src/plugins/i18n-types/i18n-types.services.ts b/apps/papra-client/src/plugins/i18n-types/i18n-types.services.ts index 6f08b81..637f4cc 100644 --- a/apps/papra-client/src/plugins/i18n-types/i18n-types.services.ts +++ b/apps/papra-client/src/plugins/i18n-types/i18n-types.services.ts @@ -2,8 +2,11 @@ import { readFile, writeFile } from 'node:fs/promises'; import path from 'node:path'; import { cwd as getCwd } from 'node:process'; +import { fileURLToPath } from 'node:url'; import { parse } from 'yaml'; +const filename = fileURLToPath(import.meta.url); + export async function generateI18nTypes({ cwd = getCwd() }: { cwd?: string } = {}) { try { const yamlPath = path.join(cwd, 'src/locales/en.yml'); @@ -17,7 +20,7 @@ export async function generateI18nTypes({ cwd = getCwd() }: { cwd?: string } = { // Do not manually edit this file. // This file is dynamically generated when the dev server runs (or using the \`pnpm script:generate-i18n-types\` command). // Keys are extracted from the en.yml file. -// Source code : ${path.relative(cwd, __filename)} +// Source code : ${path.relative(cwd, filename)} export type LocaleKeys =\n${localKeys.map(key => ` | '${key}'`).join('\n')}; `.trimStart(); diff --git a/apps/papra-server/eslint.config.js b/apps/papra-server/eslint.config.js index e0175da..096bd2d 100644 --- a/apps/papra-server/eslint.config.js +++ b/apps/papra-server/eslint.config.js @@ -1,6 +1,14 @@ import antfu from '@antfu/eslint-config'; export default antfu({ + typescript: { + tsconfigPath: './tsconfig.json', + overridesTypeAware: { + 'ts/no-misused-promises': ['error', { checksVoidReturn: false }], + 'ts/strict-boolean-expressions': ['error', { allowNullableObject: true }], + }, + + }, stylistic: { semi: true, }, diff --git a/apps/papra-server/src/modules/api-keys/api-keys.constants.ts b/apps/papra-server/src/modules/api-keys/api-keys.constants.ts index dbce4d7..ba84f67 100644 --- a/apps/papra-server/src/modules/api-keys/api-keys.constants.ts +++ b/apps/papra-server/src/modules/api-keys/api-keys.constants.ts @@ -1,3 +1,8 @@ +import { createPrefixedIdRegex } from '../shared/random/ids'; + +export const API_KEY_ID_PREFIX = 'ak'; +export const API_KEY_ID_REGEX = createPrefixedIdRegex({ prefix: API_KEY_ID_PREFIX }); + export const API_KEY_PREFIX = 'ppapi'; export const API_KEY_TOKEN_LENGTH = 64; diff --git a/apps/papra-server/src/modules/api-keys/api-keys.middlewares.ts b/apps/papra-server/src/modules/api-keys/api-keys.middlewares.ts index 3d89142..a621c0c 100644 --- a/apps/papra-server/src/modules/api-keys/api-keys.middlewares.ts +++ b/apps/papra-server/src/modules/api-keys/api-keys.middlewares.ts @@ -3,6 +3,7 @@ import type { Context } from '../app/server.types'; import { createMiddleware } from 'hono/factory'; import { createUnauthorizedError } from '../app/auth/auth.errors'; import { getAuthorizationHeader } from '../shared/headers/headers.models'; +import { isNil } from '../shared/utils'; import { createApiKeysRepository } from './api-keys.repository'; import { getApiKey } from './api-keys.usecases'; @@ -14,7 +15,7 @@ export function createApiKeyMiddleware({ db }: { db: Database }) { return createMiddleware(async (context: Context, next) => { const { authorizationHeader } = getAuthorizationHeader({ context }); - if (!authorizationHeader) { + if (isNil(authorizationHeader)) { return next(); } @@ -30,6 +31,11 @@ export function createApiKeyMiddleware({ db }: { db: Database }) { throw createUnauthorizedError(); } + if (isNil(token)) { + // For type safety + throw createUnauthorizedError(); + } + const { apiKey } = await getApiKey({ token, apiKeyRepository }); if (apiKey) { diff --git a/apps/papra-server/src/modules/api-keys/api-keys.repository.ts b/apps/papra-server/src/modules/api-keys/api-keys.repository.ts index 68c3e57..53205fc 100644 --- a/apps/papra-server/src/modules/api-keys/api-keys.repository.ts +++ b/apps/papra-server/src/modules/api-keys/api-keys.repository.ts @@ -5,6 +5,7 @@ import { injectArguments } from '@corentinth/chisels'; import { and, eq, getTableColumns, inArray } from 'drizzle-orm'; import { omit, pick } from 'lodash-es'; import { organizationMembersTable, organizationsTable } from '../organizations/organizations.table'; +import { createError } from '../shared/errors/errors'; import { createLogger } from '../shared/logger/logger'; import { apiKeyOrganizationsTable, apiKeysTable } from './api-keys.tables'; @@ -58,6 +59,16 @@ async function saveApiKey({ }) .returning(); + if (!apiKey) { + // Very unlikely to happen as the insertion should throw an issue, it's for type safety + throw createError({ + message: 'Error while creating api key', + code: 'api-keys.create_error', + statusCode: 500, + isInternal: true, + }); + } + if (organizationIds && organizationIds.length > 0) { const apiKeyId = apiKey.id; diff --git a/apps/papra-server/src/modules/api-keys/api-keys.routes.ts b/apps/papra-server/src/modules/api-keys/api-keys.routes.ts index 2ea0df8..bfd5013 100644 --- a/apps/papra-server/src/modules/api-keys/api-keys.routes.ts +++ b/apps/papra-server/src/modules/api-keys/api-keys.routes.ts @@ -4,9 +4,10 @@ import { z } from 'zod'; import { requireAuthentication } from '../app/auth/auth.middleware'; import { getUser } from '../app/auth/auth.models'; import { createError } from '../shared/errors/errors'; -import { validateJsonBody } from '../shared/validation/validation'; +import { validateJsonBody, validateParams } from '../shared/validation/validation'; import { API_KEY_PERMISSIONS_VALUES } from './api-keys.constants'; import { createApiKeysRepository } from './api-keys.repository'; +import { apiKeyIdSchema } from './api-keys.schemas'; import { createApiKey } from './api-keys.usecases'; export function registerApiKeysRoutes(context: RouteDefinitionContext) { @@ -85,11 +86,14 @@ function setupDeleteApiKeyRoute({ app, db }: RouteDefinitionContext) { app.delete( '/api/api-keys/:apiKeyId', requireAuthentication(), + validateParams(z.object({ + apiKeyId: apiKeyIdSchema, + })), async (context) => { const { userId } = getUser({ context }); const apiKeyRepository = createApiKeysRepository({ db }); - const { apiKeyId } = context.req.param(); + const { apiKeyId } = context.req.valid('param'); await apiKeyRepository.deleteUserApiKey({ apiKeyId, userId }); diff --git a/apps/papra-server/src/modules/api-keys/api-keys.schemas.ts b/apps/papra-server/src/modules/api-keys/api-keys.schemas.ts new file mode 100644 index 0000000..c826396 --- /dev/null +++ b/apps/papra-server/src/modules/api-keys/api-keys.schemas.ts @@ -0,0 +1,4 @@ +import { z } from 'zod'; +import { API_KEY_ID_REGEX } from './api-keys.constants'; + +export const apiKeyIdSchema = z.string().regex(API_KEY_ID_REGEX); diff --git a/apps/papra-server/src/modules/api-keys/api-keys.tables.ts b/apps/papra-server/src/modules/api-keys/api-keys.tables.ts index 8e8b97b..e151fb4 100644 --- a/apps/papra-server/src/modules/api-keys/api-keys.tables.ts +++ b/apps/papra-server/src/modules/api-keys/api-keys.tables.ts @@ -4,11 +4,12 @@ import { index, integer, sqliteTable, text } from 'drizzle-orm/sqlite-core'; import { organizationMembersTable } from '../organizations/organizations.table'; import { createPrimaryKeyField, createTimestampColumns } from '../shared/db/columns.helpers'; import { usersTable } from '../users/users.table'; +import { API_KEY_ID_PREFIX } from './api-keys.constants'; export const apiKeysTable = sqliteTable( 'api_keys', { - ...createPrimaryKeyField({ prefix: 'ak' }), + ...createPrimaryKeyField({ prefix: API_KEY_ID_PREFIX }), ...createTimestampColumns(), name: text('name').notNull(), diff --git a/apps/papra-server/src/modules/api-keys/api-keys.usecases.test.ts b/apps/papra-server/src/modules/api-keys/api-keys.usecases.test.ts index deab0c2..ad48e9d 100644 --- a/apps/papra-server/src/modules/api-keys/api-keys.usecases.test.ts +++ b/apps/papra-server/src/modules/api-keys/api-keys.usecases.test.ts @@ -48,7 +48,7 @@ describe('api-keys usecases', () => { const { apiKey } = await getApiKey({ token: 'ppapi_HT2Hj5V8A3WHMQtVcMDB9UucqUxPU15o1aI6qOc1Oy5qBvbSEr4jZzsjuFYPqCP0', apiKeyRepository }); - expect(apiKey.id).to.eql('api_key_1'); + expect(apiKey?.id).to.eql('api_key_1'); }); }); }); diff --git a/apps/papra-server/src/modules/app/auth/auth.models.ts b/apps/papra-server/src/modules/app/auth/auth.models.ts index f4e2a50..66e403d 100644 --- a/apps/papra-server/src/modules/app/auth/auth.models.ts +++ b/apps/papra-server/src/modules/app/auth/auth.models.ts @@ -4,11 +4,12 @@ import type { Context } from '../server.types'; import type { Session } from './auth.types'; import { uniq } from 'lodash-es'; import { createError } from '../../shared/errors/errors'; +import { isNil } from '../../shared/utils'; export function getUser({ context }: { context: Context }) { const userId = context.get('userId'); - if (!userId) { + if (isNil(userId)) { // This should never happen as getUser is called in authenticated routes // just for proper type safety throw createError({ diff --git a/apps/papra-server/src/modules/app/auth/auth.routes.ts b/apps/papra-server/src/modules/app/auth/auth.routes.ts index 3503a9b..0698d15 100644 --- a/apps/papra-server/src/modules/app/auth/auth.routes.ts +++ b/apps/papra-server/src/modules/app/auth/auth.routes.ts @@ -1,12 +1,13 @@ import type { Context, RouteDefinitionContext } from '../server.types'; import type { Session } from './auth.types'; import { get } from 'lodash-es'; +import { isDefined } from '../../shared/utils'; export function registerAuthRoutes({ app, auth, config }: RouteDefinitionContext) { app.on( ['POST', 'GET'], '/api/auth/*', - context => auth.handler(context.req.raw), + async context => auth.handler(context.req.raw), ); app.use('*', async (context: Context, next) => { @@ -23,9 +24,9 @@ export function registerAuthRoutes({ app, auth, config }: RouteDefinitionContext if (config.env === 'test') { app.use('*', async (context: Context, next) => { - const overrideUserId = get(context.env, 'loggedInUserId') as string | undefined; + const overrideUserId: unknown = get(context.env, 'loggedInUserId'); - if (overrideUserId) { + if (isDefined(overrideUserId) && typeof overrideUserId === 'string') { context.set('userId', overrideUserId); context.set('session', {} as Session); context.set('authType', 'session'); diff --git a/apps/papra-server/src/modules/app/auth/auth.services.ts b/apps/papra-server/src/modules/app/auth/auth.services.ts index d5141c1..185eff8 100644 --- a/apps/papra-server/src/modules/app/auth/auth.services.ts +++ b/apps/papra-server/src/modules/app/auth/auth.services.ts @@ -36,9 +36,7 @@ export function getAuth({ logger: { disabled: false, log: (baseLevel, message) => { - const level = (baseLevel in logger ? baseLevel : 'info') as keyof typeof logger; - - logger[level](message); + logger[baseLevel ?? 'info'](message); }, }, emailAndPassword: { diff --git a/apps/papra-server/src/modules/app/database/database.test-utils.ts b/apps/papra-server/src/modules/app/database/database.test-utils.ts index 3577aa4..b6c5cbe 100644 --- a/apps/papra-server/src/modules/app/database/database.test-utils.ts +++ b/apps/papra-server/src/modules/app/database/database.test-utils.ts @@ -53,7 +53,7 @@ async function seedDatabase({ db, ...seedRows }: { db: Database } & SeedTablesRo await Promise.all( Object .entries(seedRows) - .map(([table, rows]) => db + .map(async ([table, rows]) => db .insert(seedTables[table as keyof typeof seedTables]) .values(rows) .execute(), diff --git a/apps/papra-server/src/modules/app/health-check/health-check.repository.ts b/apps/papra-server/src/modules/app/health-check/health-check.repository.ts index d804d46..f989980 100644 --- a/apps/papra-server/src/modules/app/health-check/health-check.repository.ts +++ b/apps/papra-server/src/modules/app/health-check/health-check.repository.ts @@ -5,5 +5,5 @@ import { sql } from 'drizzle-orm'; export async function isDatabaseHealthy({ db }: { db: Database }) { const [result, error] = await safely(db.run(sql`SELECT 1;`)); - return error === null && result.rows.length > 0 && result.rows[0]['1'] === 1; + return error === null && result.rows.length > 0 && result.rows[0]?.['1'] === 1; } diff --git a/apps/papra-server/src/modules/app/middlewares/errors.middleware.test.ts b/apps/papra-server/src/modules/app/middlewares/errors.middleware.test.ts index 98bde48..fc85f4b 100644 --- a/apps/papra-server/src/modules/app/middlewares/errors.middleware.test.ts +++ b/apps/papra-server/src/modules/app/middlewares/errors.middleware.test.ts @@ -1,3 +1,4 @@ +import type { ServerInstanceGenerics } from '../server.types'; import { Hono } from 'hono'; import { describe, expect, test } from 'vitest'; import { createError } from '../../shared/errors/errors'; @@ -6,8 +7,8 @@ import { registerErrorMiddleware } from './errors.middleware'; describe('errors middleware', () => { describe('registerErrorMiddleware', () => { test('when a non-internal custom error is thrown with a status code, the error is returned', async () => { - const app = new Hono(); - registerErrorMiddleware({ app: app as any }); + const app = new Hono(); + registerErrorMiddleware({ app }); app.get('/error', async () => { throw createError({ @@ -29,8 +30,8 @@ describe('errors middleware', () => { }); test('when an unknown error is thrown, a 500 error is returned with a generic message', async () => { - const app = new Hono(); - registerErrorMiddleware({ app: app as any }); + const app = new Hono(); + registerErrorMiddleware({ app }); app.get('/error', async () => { throw new Error('Unknown error'); @@ -48,8 +49,8 @@ describe('errors middleware', () => { }); test('when a custom error is marked as internal, a 500 error is returned with a generic message', async () => { - const app = new Hono(); - registerErrorMiddleware({ app: app as any }); + const app = new Hono(); + registerErrorMiddleware({ app }); app.get('/error', async () => { throw createError({ @@ -72,8 +73,8 @@ describe('errors middleware', () => { }); test('when querying an unknown route, a 404 error is returned', async () => { - const app = new Hono(); - registerErrorMiddleware({ app: app as any }); + const app = new Hono(); + registerErrorMiddleware({ app }); const response = await app.request('/unknown-route', { method: 'GET' }); diff --git a/apps/papra-server/src/modules/app/middlewares/timeout.middleware.test.ts b/apps/papra-server/src/modules/app/middlewares/timeout.middleware.test.ts index 9dbd10f..224e16f 100644 --- a/apps/papra-server/src/modules/app/middlewares/timeout.middleware.test.ts +++ b/apps/papra-server/src/modules/app/middlewares/timeout.middleware.test.ts @@ -1,3 +1,4 @@ +import type { ServerInstanceGenerics } from '../server.types'; import { Hono } from 'hono'; import { describe, expect, test } from 'vitest'; import { overrideConfig } from '../../config/config.test-utils'; @@ -9,8 +10,8 @@ describe('middlewares', () => { test('when a request last longer than the config timeout, a 504 error is raised', async () => { const config = overrideConfig({ server: { routeTimeoutMs: 50 } }); - const app = new Hono<{ Variables: { config: any } }>(); - registerErrorMiddleware({ app: app as any }); + const app = new Hono(); + registerErrorMiddleware({ app }); app.get( '/should-timeout', diff --git a/apps/papra-server/src/modules/app/server.routes.test.ts b/apps/papra-server/src/modules/app/server.routes.test.ts index c9e928e..f2c5905 100644 --- a/apps/papra-server/src/modules/app/server.routes.test.ts +++ b/apps/papra-server/src/modules/app/server.routes.test.ts @@ -17,7 +17,7 @@ function setValidParams(path: string) { .replaceAll(':invitationId', 'inv_101010101010101010101010'); // throw if there are any remaining params - if (newPath.match(/:(\w+)/g)) { + if (newPath.match(/:\w+/g)) { throw new Error(`Add a dummy value for the params in ${path}`); } diff --git a/apps/papra-server/src/modules/config/config.routes.ts b/apps/papra-server/src/modules/config/config.routes.ts index 770307e..12cfad2 100644 --- a/apps/papra-server/src/modules/config/config.routes.ts +++ b/apps/papra-server/src/modules/config/config.routes.ts @@ -1,7 +1,7 @@ import type { RouteDefinitionContext } from '../app/server.types'; import { getPublicConfig } from './config.models'; -export async function registerConfigRoutes(context: RouteDefinitionContext) { +export function registerConfigRoutes(context: RouteDefinitionContext) { setupGetPublicConfigRoute(context); } diff --git a/apps/papra-server/src/modules/documents/documents.models.ts b/apps/papra-server/src/modules/documents/documents.models.ts index 7cacc61..fcad2d3 100644 --- a/apps/papra-server/src/modules/documents/documents.models.ts +++ b/apps/papra-server/src/modules/documents/documents.models.ts @@ -1,5 +1,6 @@ import { getExtension } from '../shared/files/file-names'; import { generateId } from '../shared/random/ids'; +import { isDefined } from '../shared/utils'; import { ORIGINAL_DOCUMENTS_STORAGE_KEY } from './documents.constants'; export function joinStorageKeyParts(...parts: string[]) { @@ -9,7 +10,7 @@ export function joinStorageKeyParts(...parts: string[]) { export function buildOriginalDocumentKey({ documentId, organizationId, fileName }: { documentId: string; organizationId: string; fileName: string }) { const { extension } = getExtension({ fileName }); - const newFileName = extension ? `${documentId}.${extension}` : documentId; + const newFileName = isDefined(extension) ? `${documentId}.${extension}` : documentId; const originalDocumentStorageKey = joinStorageKeyParts(organizationId, ORIGINAL_DOCUMENTS_STORAGE_KEY, newFileName); diff --git a/apps/papra-server/src/modules/documents/documents.repository.ts b/apps/papra-server/src/modules/documents/documents.repository.ts index 8b408f6..d2bc524 100644 --- a/apps/papra-server/src/modules/documents/documents.repository.ts +++ b/apps/papra-server/src/modules/documents/documents.repository.ts @@ -4,11 +4,13 @@ import { injectArguments, safely } from '@corentinth/chisels'; import { subDays } from 'date-fns'; import { and, count, desc, eq, getTableColumns, lt, sql, sum } from 'drizzle-orm'; import { omit } from 'lodash-es'; +import { createOrganizationNotFoundError } from '../organizations/organizations.errors'; import { isUniqueConstraintError } from '../shared/db/constraints.models'; import { withPagination } from '../shared/db/pagination'; -import { omitUndefined } from '../shared/utils'; +import { createError } from '../shared/errors/errors'; +import { isDefined, isNil, omitUndefined } from '../shared/utils'; import { documentsTagsTable, tagsTable } from '../tags/tags.table'; -import { createDocumentAlreadyExistsError } from './documents.errors'; +import { createDocumentAlreadyExistsError, createDocumentNotFoundError } from './documents.errors'; import { documentsTable } from './documents.table'; export type DocumentsRepository = ReturnType; @@ -57,13 +59,27 @@ async function saveOrganizationDocument({ db, ...documentToInsert }: { db: Datab throw createDocumentAlreadyExistsError(); } + if (error) { + throw error; + } + const [document] = documents ?? []; + if (isNil(document)) { + // Very unlikely to happen as the insertion throws an issue, it's for type safety + throw createError({ + message: 'Error while saving document', + code: 'documents.save_error', + statusCode: 500, + isInternal: true, + }); + } + return { document }; } async function getOrganizationDocumentsCount({ organizationId, filters, db }: { organizationId: string; filters?: { tags?: string[] }; db: Database }) { - const [{ documentsCount }] = await db + const [record] = await db .select({ documentsCount: count(documentsTable.id), }) @@ -77,11 +93,17 @@ async function getOrganizationDocumentsCount({ organizationId, filters, db }: { ), ); + if (isNil(record)) { + throw createOrganizationNotFoundError(); + } + + const { documentsCount } = record; + return { documentsCount }; } async function getOrganizationDeletedDocumentsCount({ organizationId, db }: { organizationId: string; db: Database }) { - const [{ documentsCount }] = await db + const [record] = await db .select({ documentsCount: count(documentsTable.id), }) @@ -93,6 +115,12 @@ async function getOrganizationDeletedDocumentsCount({ organizationId, db }: { or ), ); + if (isNil(record)) { + throw createOrganizationNotFoundError(); + } + + const { documentsCount } = record; + return { documentsCount }; } @@ -145,7 +173,7 @@ async function getOrganizationDocuments({ } if (tag) { - acc[document.id].tags.push(tag); + acc[document.id]!.tags.push(tag); } return acc; @@ -235,8 +263,8 @@ async function restoreDocument({ documentId, organizationId, name, userId, db }: isDeleted: false, deletedBy: null, deletedAt: null, - ...(name ? { name, originalName: name } : {}), - ...(userId ? { createdBy: userId } : {}), + ...(isDefined(name) ? { name, originalName: name } : {}), + ...(isDefined(userId) ? { createdBy: userId } : {}), }) .where( and( @@ -246,6 +274,10 @@ async function restoreDocument({ documentId, organizationId, name, userId, db }: ) .returning(); + if (isNil(document)) { + throw createDocumentNotFoundError(); + } + return { document }; } @@ -294,7 +326,7 @@ async function searchOrganizationDocuments({ organizationId, searchQuery, pageIn } async function getOrganizationStats({ organizationId, db }: { organizationId: string; db: Database }) { - const [{ documentsCount, documentsSize }] = await db + const [record] = await db .select({ documentsCount: count(documentsTable.id), documentsSize: sum(documentsTable.originalSize), @@ -307,6 +339,12 @@ async function getOrganizationStats({ organizationId, db }: { organizationId: st ), ); + if (isNil(record)) { + throw createOrganizationNotFoundError(); + } + + const { documentsCount, documentsSize } = record; + return { documentsCount, documentsSize: Number(documentsSize ?? 0), diff --git a/apps/papra-server/src/modules/documents/documents.routes.ts b/apps/papra-server/src/modules/documents/documents.routes.ts index cbb25ed..625d3c3 100644 --- a/apps/papra-server/src/modules/documents/documents.routes.ts +++ b/apps/papra-server/src/modules/documents/documents.routes.ts @@ -7,6 +7,7 @@ import { organizationIdSchema } from '../organizations/organization.schemas'; import { createOrganizationsRepository } from '../organizations/organizations.repository'; import { ensureUserIsInOrganization } from '../organizations/organizations.usecases'; import { createError } from '../shared/errors/errors'; +import { isNil } from '../shared/utils'; import { validateFormData, validateJsonBody, validateParams, validateQuery } from '../shared/validation/validation'; import { createWebhookRepository } from '../webhooks/webhook.repository'; import { triggerWebhooks } from '../webhooks/webhook.usecases'; @@ -38,7 +39,7 @@ function setupCreateDocumentRoute({ app, config, db, trackingServices }: RouteDe app.post( '/api/organizations/:organizationId/documents', requireAuthentication({ apiKeyPermissions: ['documents:create'] }), - (context, next) => { + async (context, next) => { const { maxUploadSize } = config.documentsStorage; if (!isDocumentSizeLimitEnabled({ maxUploadSize })) { @@ -56,6 +57,7 @@ function setupCreateDocumentRoute({ app, config, db, trackingServices }: RouteDe }, }); + // eslint-disable-next-line ts/no-unsafe-argument return middleware(context, next); }, @@ -72,7 +74,7 @@ function setupCreateDocumentRoute({ app, config, db, trackingServices }: RouteDe const { file, ocrLanguages } = context.req.valid('form'); const { organizationId } = context.req.valid('param'); - if (!file) { + if (isNil(file)) { throw createError({ message: 'No file provided, please upload a file using the "file" key.', code: 'document.no_file', diff --git a/apps/papra-server/src/modules/documents/documents.usecases.ts b/apps/papra-server/src/modules/documents/documents.usecases.ts index 6228f3e..2cee115 100644 --- a/apps/papra-server/src/modules/documents/documents.usecases.ts +++ b/apps/papra-server/src/modules/documents/documents.usecases.ts @@ -17,6 +17,7 @@ import pLimit from 'p-limit'; import { checkIfOrganizationCanCreateNewDocument } from '../organizations/organizations.usecases'; import { createPlansRepository } from '../plans/plans.repository'; import { createLogger } from '../shared/logger/logger'; +import { isDefined } from '../shared/utils'; import { createSubscriptionsRepository } from '../subscriptions/subscriptions.repository'; import { createTaggingRulesRepository } from '../tagging-rules/tagging-rules.repository'; import { applyTaggingRules } from '../tagging-rules/tagging-rules.usecases'; @@ -100,28 +101,28 @@ export async function createDocument({ const { document } = existingDocument ? await handleExistingDocument({ - existingDocument, - fileName, - organizationId, - documentsRepository, - tagsRepository, - logger, - }) + existingDocument, + fileName, + organizationId, + documentsRepository, + tagsRepository, + logger, + }) : await createNewDocument({ - file, - fileName, - size, - mimeType, - hash, - userId, - organizationId, - documentsRepository, - documentsStorageService, - generateDocumentId, - trackingServices, - ocrLanguages, - logger, - }); + file, + fileName, + size, + mimeType, + hash, + userId, + organizationId, + documentsRepository, + documentsStorageService, + generateDocumentId, + trackingServices, + ocrLanguages, + logger, + }); deferRegisterDocumentActivityLog({ documentId: document.id, @@ -195,7 +196,7 @@ async function handleExistingDocument({ tagsRepository: TagsRepository; logger: Logger; }) { - if (existingDocument && !existingDocument.isDeleted) { + if (!existingDocument.isDeleted) { throw createDocumentAlreadyExistsError(); } @@ -277,7 +278,7 @@ async function createNewDocument({ throw error; } - if (userId) { + if (isDefined(userId)) { trackingServices.captureUserEvent({ userId, event: 'Document created' }); } @@ -354,7 +355,7 @@ export async function deleteExpiredDocuments({ const limit = pLimit(10); await Promise.all( - documents.map(document => limit(async () => { + documents.map(async document => limit(async () => { const [, error] = await safely(hardDeleteDocument({ document, documentsRepository, documentsStorageService })); if (error) { @@ -408,6 +409,6 @@ export async function deleteAllTrashDocuments({ const limit = pLimit(10); await Promise.all( - documents.map(document => limit(() => hardDeleteDocument({ document, documentsRepository, documentsStorageService }))), + documents.map(async document => limit(async () => hardDeleteDocument({ document, documentsRepository, documentsStorageService }))), ); } diff --git a/apps/papra-server/src/modules/documents/storage/documents.storage.services.ts b/apps/papra-server/src/modules/documents/storage/documents.storage.services.ts index 294989c..2c7d69d 100644 --- a/apps/papra-server/src/modules/documents/storage/documents.storage.services.ts +++ b/apps/papra-server/src/modules/documents/storage/documents.storage.services.ts @@ -1,5 +1,6 @@ import type { Config } from '../../config/config.types'; import { createError } from '../../shared/errors/errors'; +import { isNil } from '../../shared/utils'; import { AZ_BLOB_STORAGE_DRIVER_NAME, azBlobStorageDriverFactory } from './drivers/az-blob/az-blob.storage-driver'; import { B2_STORAGE_DRIVER_NAME, b2StorageDriverFactory } from './drivers/b2/b2.storage-driver'; import { FS_STORAGE_DRIVER_NAME, fsStorageDriverFactory } from './drivers/fs/fs.storage-driver'; @@ -21,7 +22,7 @@ export async function createDocumentStorageService({ config }: { config: Config const storageDriverFactory = storageDriverFactories[storageDriverName]; - if (!storageDriverFactory) { + if (isNil(storageDriverFactory)) { throw createError({ message: `Unknown storage driver: ${storageDriverName}`, code: 'storage_driver.unknown_driver', diff --git a/apps/papra-server/src/modules/documents/storage/drivers/b2/b2.storage-driver.ts b/apps/papra-server/src/modules/documents/storage/drivers/b2/b2.storage-driver.ts index 5cf9188..762f32f 100644 --- a/apps/papra-server/src/modules/documents/storage/drivers/b2/b2.storage-driver.ts +++ b/apps/papra-server/src/modules/documents/storage/drivers/b2/b2.storage-driver.ts @@ -1,6 +1,7 @@ import { Buffer } from 'node:buffer'; import B2 from 'backblaze-b2'; +import { isNil } from '../../../../shared/utils'; import { createFileNotFoundError } from '../../document-storage.errors'; import { defineStorageDriver } from '../drivers.models'; @@ -22,8 +23,10 @@ export const b2StorageDriverFactory = defineStorageDriver(async ({ config }) => bucketId, }); const upload = await b2Client.uploadFile({ - uploadUrl: getUploadUrl.data.uploadUrl, - uploadAuthToken: getUploadUrl.data.authorizationToken, + // eslint-disable-next-line ts/no-unsafe-member-access + uploadUrl: getUploadUrl.data?.uploadUrl as string, + // eslint-disable-next-line ts/no-unsafe-member-access + uploadAuthToken: getUploadUrl.data?.authorizationToken as string, fileName: storageKey, data: Buffer.from(await file.arrayBuffer()), }); @@ -34,15 +37,18 @@ export const b2StorageDriverFactory = defineStorageDriver(async ({ config }) => }, getFileStream: async ({ storageKey }) => { await b2Client.authorize(); + const response = await b2Client.downloadFileByName({ bucketName, fileName: storageKey, responseType: 'stream', }); - if (!response.data) { + + if (isNil(response.data)) { throw createFileNotFoundError(); } - return { fileStream: response.data }; + + return { fileStream: response.data as ReadableStream }; }, deleteFile: async ({ storageKey }) => { await b2Client.hideFile({ diff --git a/apps/papra-server/src/modules/documents/storage/drivers/fs/fs.storage-driver.test.ts b/apps/papra-server/src/modules/documents/storage/drivers/fs/fs.storage-driver.test.ts index a985fbe..954d2f3 100644 --- a/apps/papra-server/src/modules/documents/storage/drivers/fs/fs.storage-driver.test.ts +++ b/apps/papra-server/src/modules/documents/storage/drivers/fs/fs.storage-driver.test.ts @@ -94,7 +94,7 @@ describe('storage driver', () => { const { fileStream } = await fsStorageDriver.getFileStream({ storageKey: 'org_1/text-file.txt' }); - const chunks: Uint8Array[] = []; + const chunks: unknown[] = []; for await (const chunk of fileStream) { chunks.push(chunk); } diff --git a/apps/papra-server/src/modules/documents/storage/drivers/memory/memory.storage-driver.test.ts b/apps/papra-server/src/modules/documents/storage/drivers/memory/memory.storage-driver.test.ts index ed75899..779c893 100644 --- a/apps/papra-server/src/modules/documents/storage/drivers/memory/memory.storage-driver.test.ts +++ b/apps/papra-server/src/modules/documents/storage/drivers/memory/memory.storage-driver.test.ts @@ -43,7 +43,7 @@ describe('memory storage-driver', () => { const entries = Array.from(storage.entries()); expect(entries).to.have.length(1); - const [key, file] = entries[0]; + const [key, file] = entries[0] as [string, File]; expect(key).to.eql('org_1/text-file.txt'); expect(file).to.be.a('File'); diff --git a/apps/papra-server/src/modules/emails/emails.services.ts b/apps/papra-server/src/modules/emails/emails.services.ts index fa5cc41..4a4ac5c 100644 --- a/apps/papra-server/src/modules/emails/emails.services.ts +++ b/apps/papra-server/src/modules/emails/emails.services.ts @@ -1,7 +1,9 @@ import type { Config } from '../config/config.types'; import type { EmailDriverName } from './drivers/email-driver'; +import type { EmailDriverFactory } from './emails.types'; import { createError } from '../shared/errors/errors'; import { createLogger } from '../shared/logger/logger'; +import { isNil } from '../shared/utils'; import { emailDrivers } from './drivers/email-driver'; export type EmailsServices = ReturnType; @@ -9,9 +11,9 @@ export type EmailsServices = ReturnType; export function createEmailsServices({ config }: { config: Config }) { const { driverName } = config.emails; - const emailDriver = emailDrivers[driverName as EmailDriverName]; + const emailDriver: EmailDriverFactory | undefined = emailDrivers[driverName as EmailDriverName]; - if (!emailDriver) { + if (isNil(emailDriver)) { throw createError({ message: `Invalid email driver ${driverName}`, code: 'emails.invalid_driver', diff --git a/apps/papra-server/src/modules/ingestion-folders/ingestion-folder.models.ts b/apps/papra-server/src/modules/ingestion-folders/ingestion-folder.models.ts index b7e2cdd..7440ce9 100644 --- a/apps/papra-server/src/modules/ingestion-folders/ingestion-folder.models.ts +++ b/apps/papra-server/src/modules/ingestion-folders/ingestion-folder.models.ts @@ -1,5 +1,6 @@ import { isAbsolute, join, parse, sep as pathSeparator, relative } from 'node:path'; import { ORGANIZATION_ID_REGEX } from '../organizations/organizations.constants'; +import { isNil } from '../shared/utils'; export function normalizeFilePathToIngestionFolder({ filePath, @@ -16,7 +17,7 @@ export function normalizeFilePathToIngestionFolder({ export function getOrganizationIdFromFilePath({ relativeFilePath }: { relativeFilePath: string }) { const [maybeOrganizationId] = relativeFilePath.split(pathSeparator); - if (!maybeOrganizationId || !ORGANIZATION_ID_REGEX.test(maybeOrganizationId)) { + if (isNil(maybeOrganizationId) || !ORGANIZATION_ID_REGEX.test(maybeOrganizationId)) { return { organizationId: undefined }; } diff --git a/apps/papra-server/src/modules/ingestion-folders/ingestion-folders.services.ts b/apps/papra-server/src/modules/ingestion-folders/ingestion-folders.services.ts index 80e776c..488be8e 100644 --- a/apps/papra-server/src/modules/ingestion-folders/ingestion-folders.services.ts +++ b/apps/papra-server/src/modules/ingestion-folders/ingestion-folders.services.ts @@ -15,8 +15,10 @@ export async function getFile({ fs?: Pick; }) { const buffer = await fs.readFile({ filePath }); - // OR pipes since lookup returns false if the mime type is not found - const mimeType = mime.lookup(filePath) || 'application/octet-stream'; + // lookup returns false if the mime type is not found + const lookedUpMimeType = mime.lookup(filePath); + const mimeType = lookedUpMimeType === false ? 'application/octet-stream' : lookedUpMimeType; + const { base: fileName } = parse(filePath); const file = new File([buffer], fileName, { type: mimeType }); diff --git a/apps/papra-server/src/modules/ingestion-folders/ingestion-folders.usecases.test.ts b/apps/papra-server/src/modules/ingestion-folders/ingestion-folders.usecases.test.ts index 4256ae2..788bdec 100644 --- a/apps/papra-server/src/modules/ingestion-folders/ingestion-folders.usecases.test.ts +++ b/apps/papra-server/src/modules/ingestion-folders/ingestion-folders.usecases.test.ts @@ -74,7 +74,7 @@ describe('ingestion-folders usecases', () => { expect(files).to.have.length(1); - const [file] = files; + const [file] = files as [File]; expect(file.name).to.equal('hello.md'); expect(file.size).to.equal(11); @@ -175,7 +175,7 @@ describe('ingestion-folders usecases', () => { expect(files).to.have.length(1); - const [file] = files; + const [file] = files as [File]; expect(file.name).to.equal('hello.md'); expect(file.size).to.equal(11); @@ -232,6 +232,7 @@ describe('ingestion-folders usecases', () => { ingestionFolder: { folderRootPath: '/apps/papra/ingestion', postProcessing: { + // eslint-disable-next-line ts/no-unsafe-assignment strategy: 'unknown' as any, }, }, @@ -278,7 +279,7 @@ describe('ingestion-folders usecases', () => { expect(files).to.have.length(1); - const [file] = files; + const [file] = files as [File]; expect(file.name).to.equal('hello.md'); expect(file.size).to.equal(11); @@ -303,6 +304,7 @@ describe('ingestion-folders usecases', () => { ingestionFolder: { folderRootPath: '/apps/papra/ingestion', postProcessing: { + // eslint-disable-next-line ts/no-unsafe-assignment strategy: 'unknown' as any, }, }, @@ -477,7 +479,7 @@ describe('ingestion-folders usecases', () => { const documents = await db.select().from(documentsTable); expect(documents).to.have.length(1); - expect(documents[0].id).to.equal('doc_1'); + expect(documents[0]?.id).to.equal('doc_1'); // Check fs expect(vol.toJSON()).to.deep.equal({ @@ -553,7 +555,7 @@ describe('ingestion-folders usecases', () => { const documents = await db.select().from(documentsTable); expect(documents).to.have.length(1); - expect(documents[0].id).to.equal('doc_1'); + expect(documents[0]?.id).to.equal('doc_1'); // Check fs expect(vol.toJSON()).to.deep.equal({ diff --git a/apps/papra-server/src/modules/ingestion-folders/ingestion-folders.usecases.ts b/apps/papra-server/src/modules/ingestion-folders/ingestion-folders.usecases.ts index 91209d8..d2677da 100644 --- a/apps/papra-server/src/modules/ingestion-folders/ingestion-folders.usecases.ts +++ b/apps/papra-server/src/modules/ingestion-folders/ingestion-folders.usecases.ts @@ -18,6 +18,7 @@ import { isErrorWithCode } from '../shared/errors/errors'; import { createFsServices } from '../shared/fs/fs.services'; import { createLogger } from '../shared/logger/logger'; import { getRootDirPath } from '../shared/path'; +import { isNil } from '../shared/utils'; import { addTimestampToFilename, getAbsolutePathFromFolderRelativeToOrganizationIngestionFolder, getOrganizationIdFromFilePath, isFileInDoneFolder, isFileInErrorFolder, normalizeFilePathToIngestionFolder } from './ingestion-folder.models'; import { createInvalidPostProcessingStrategyError } from './ingestion-folders.errors'; import { getFile } from './ingestion-folders.services'; @@ -58,8 +59,8 @@ export function createIngestionFolderWatcher({ ignored, }, ) - .on('add', (fileMaybeCwdRelativePath) => { - processingQueue.add(async () => { + .on('add', async (fileMaybeCwdRelativePath) => { + await processingQueue.add(async () => { const filePath = isAbsolute(fileMaybeCwdRelativePath) ? fileMaybeCwdRelativePath : join(cwd, fileMaybeCwdRelativePath); logger.info({ filePath }, 'Processing file'); @@ -116,7 +117,7 @@ export async function processFile({ const { organizationId } = await getFileOrganizationId({ filePath, ingestionFolderPath, organizationsRepository }); - if (!organizationId) { + if (isNil(organizationId)) { logger.warn({ filePath }, 'A file in the ingestion folder is not located in an organization ingestion folder, skipping'); return; } @@ -149,7 +150,7 @@ export async function processFile({ logger.info({ filePath }, 'Document not inserted because it already exists'); } - if (result) { + if (result?.document) { const { document } = result; logger.info({ documentId: document.id }, 'Document imported from ingestion folder'); @@ -195,12 +196,16 @@ async function getFileOrganizationId({ filePath, ingestionFolderPath, organizati const { organizationId } = getOrganizationIdFromFilePath({ relativeFilePath }); - if (!organizationId) { + if (isNil(organizationId)) { return { organizationId: undefined }; } const { organization } = await organizationsRepository.getOrganizationById({ organizationId }); + if (isNil(organization)) { + return { organizationId: undefined }; + } + return { organizationId: organization.id }; } diff --git a/apps/papra-server/src/modules/intake-emails/intake-emails.models.ts b/apps/papra-server/src/modules/intake-emails/intake-emails.models.ts index d92dade..73adecc 100644 --- a/apps/papra-server/src/modules/intake-emails/intake-emails.models.ts +++ b/apps/papra-server/src/modules/intake-emails/intake-emails.models.ts @@ -1,3 +1,6 @@ +import { createError } from '../shared/errors/errors'; +import { isDefined, isNil } from '../shared/utils'; + export function buildEmailAddress({ username, domain, @@ -7,11 +10,20 @@ export function buildEmailAddress({ domain: string; plusPart?: string; }) { - return `${username}${plusPart ? `+${plusPart}` : ''}@${domain}`; + return `${username}${isDefined(plusPart) ? `+${plusPart}` : ''}@${domain}`; } export function parseEmailAddress({ email }: { email: string }) { const [fullUsername, domain] = email.split('@'); + + if (isNil(fullUsername) || isNil(domain)) { + throw createError({ + message: 'Invalid email address', + code: 'intake_emails.invalid_email_address', + statusCode: 400, + }); + } + const [username, ...plusParts] = fullUsername.split('+'); const plusPart = plusParts.length > 0 ? plusParts.join('+') : undefined; @@ -19,7 +31,7 @@ export function parseEmailAddress({ email }: { email: string }) { } export function getEmailUsername({ email }: { email: string | undefined }) { - if (!email) { + if (isNil(email)) { return { username: undefined }; } diff --git a/apps/papra-server/src/modules/intake-emails/intake-emails.repository.ts b/apps/papra-server/src/modules/intake-emails/intake-emails.repository.ts index 5ee3d62..c78643b 100644 --- a/apps/papra-server/src/modules/intake-emails/intake-emails.repository.ts +++ b/apps/papra-server/src/modules/intake-emails/intake-emails.repository.ts @@ -1,7 +1,9 @@ import type { Database } from '../app/database/database.types'; import { injectArguments } from '@corentinth/chisels'; import { and, count, eq } from 'drizzle-orm'; +import { createError } from '../shared/errors/errors'; import { omitUndefined } from '../shared/utils'; +import { createIntakeEmailNotFoundError } from './intake-emails.errors'; import { intakeEmailsTable } from './intake-emails.tables'; export type IntakeEmailsRepository = ReturnType; @@ -24,6 +26,16 @@ export function createIntakeEmailsRepository({ db }: { db: Database }) { async function createIntakeEmail({ organizationId, emailAddress, db }: { organizationId: string; emailAddress: string; db: Database }) { const [intakeEmail] = await db.insert(intakeEmailsTable).values({ organizationId, emailAddress }).returning(); + if (!intakeEmail) { + // Very unlikely to happen as the insertion should throw an issue, it's for type safety + throw createError({ + message: 'Error while creating intake email', + code: 'intake-emails.create_error', + statusCode: 500, + isInternal: true, + }); + } + return { intakeEmail }; } @@ -44,6 +56,10 @@ async function updateIntakeEmail({ intakeEmailId, organizationId, isEnabled, all ) .returning(); + if (!intakeEmail) { + throw createIntakeEmailNotFoundError(); + } + return { intakeEmail }; } @@ -93,12 +109,18 @@ async function deleteIntakeEmail({ intakeEmailId, organizationId, db }: { intake } async function getOrganizationIntakeEmailsCount({ organizationId, db }: { organizationId: string; db: Database }) { - const [{ intakeEmailCount }] = await db + const [record] = await db .select({ intakeEmailCount: count() }) .from(intakeEmailsTable) .where( eq(intakeEmailsTable.organizationId, organizationId), ); + if (!record) { + throw createIntakeEmailNotFoundError(); + } + + const { intakeEmailCount } = record; + return { intakeEmailCount }; } diff --git a/apps/papra-server/src/modules/intake-emails/intake-emails.routes.ts b/apps/papra-server/src/modules/intake-emails/intake-emails.routes.ts index 5d9869a..d9dbe7f 100644 --- a/apps/papra-server/src/modules/intake-emails/intake-emails.routes.ts +++ b/apps/papra-server/src/modules/intake-emails/intake-emails.routes.ts @@ -12,6 +12,7 @@ import { createPlansRepository } from '../plans/plans.repository'; import { createError } from '../shared/errors/errors'; import { getHeader } from '../shared/headers/headers.models'; import { createLogger } from '../shared/logger/logger'; +import { isNil } from '../shared/utils'; import { validateFormData, validateJsonBody, validateParams } from '../shared/validation/validation'; import { createSubscriptionsRepository } from '../subscriptions/subscriptions.repository'; import { INTAKE_EMAILS_INGEST_ROUTE } from './intake-emails.constants'; @@ -166,7 +167,7 @@ function setupIngestIntakeEmailRoute({ app, db, config, trackingServices }: Rout const bodyBuffer = await context.req.arrayBuffer(); const signature = getHeader({ context, name: 'X-Signature' }); - if (!signature) { + if (isNil(signature)) { throw createError({ message: 'Signature header is required', code: 'intake_emails.signature_header_required', diff --git a/apps/papra-server/src/modules/intake-emails/intake-emails.services.ts b/apps/papra-server/src/modules/intake-emails/intake-emails.services.ts index c4aac70..f116dd9 100644 --- a/apps/papra-server/src/modules/intake-emails/intake-emails.services.ts +++ b/apps/papra-server/src/modules/intake-emails/intake-emails.services.ts @@ -1,12 +1,14 @@ import type { Config } from '../config/config.types'; import type { IntakeEmailDriverName } from './drivers/intake-emails.drivers'; +import type { IntakeEmailDriverFactory } from './drivers/intake-emails.drivers.models'; import { createError } from '../shared/errors/errors'; +import { isNil } from '../shared/utils'; import { intakeEmailDrivers } from './drivers/intake-emails.drivers'; export function createIntakeEmailsServices({ config }: { config: Config }) { - const intakeEmailDriver = intakeEmailDrivers[config.intakeEmails.driver as IntakeEmailDriverName]; + const intakeEmailDriver: IntakeEmailDriverFactory | undefined = intakeEmailDrivers[config.intakeEmails.driver as IntakeEmailDriverName]; - if (!intakeEmailDriver) { + if (isNil(intakeEmailDriver)) { throw createError({ message: `Invalid intake email driver ${config.intakeEmails.driver}`, code: 'intake-emails.invalid_driver', diff --git a/apps/papra-server/src/modules/intake-emails/intake-emails.usecases.ts b/apps/papra-server/src/modules/intake-emails/intake-emails.usecases.ts index f6b324f..1980531 100644 --- a/apps/papra-server/src/modules/intake-emails/intake-emails.usecases.ts +++ b/apps/papra-server/src/modules/intake-emails/intake-emails.usecases.ts @@ -37,7 +37,7 @@ export async function createIntakeEmail({ return { intakeEmail }; } -export function processIntakeEmailIngestion({ +export async function processIntakeEmailIngestion({ fromAddress, recipientsAddresses, attachments, @@ -51,7 +51,7 @@ export function processIntakeEmailIngestion({ createDocument: CreateDocumentUsecase; }) { return Promise.all( - recipientsAddresses.map(recipientAddress => safely( + recipientsAddresses.map(async recipientAddress => safely( ingestEmailForRecipient({ fromAddress, recipientAddress, diff --git a/apps/papra-server/src/modules/invitations/invitations.routes.ts b/apps/papra-server/src/modules/invitations/invitations.routes.ts index 18a8da3..950c848 100644 --- a/apps/papra-server/src/modules/invitations/invitations.routes.ts +++ b/apps/papra-server/src/modules/invitations/invitations.routes.ts @@ -1,12 +1,15 @@ import type { RouteDefinitionContext } from '../app/server.types'; +import z from 'zod'; import { createForbiddenError } from '../app/auth/auth.errors'; import { requireAuthentication } from '../app/auth/auth.middleware'; import { getUser } from '../app/auth/auth.models'; +import { invitationIdSchema } from '../organizations/organization.schemas'; import { ORGANIZATION_INVITATION_STATUS, ORGANIZATION_ROLES } from '../organizations/organizations.constants'; import { createOrganizationsRepository } from '../organizations/organizations.repository'; import { resendOrganizationInvitation } from '../organizations/organizations.usecases'; import { createError } from '../shared/errors/errors'; import { createLogger } from '../shared/logger/logger'; +import { validateParams } from '../shared/validation/validation'; import { createUsersRepository } from '../users/users.repository'; const logger = createLogger({ namespace: 'invitations' }); @@ -62,8 +65,11 @@ function setupAcceptInvitationRoute({ app, db }: RouteDefinitionContext) { app.post( '/api/invitations/:invitationId/accept', requireAuthentication(), + validateParams(z.object({ + invitationId: invitationIdSchema, + })), async (context) => { - const { invitationId } = context.req.param(); + const { invitationId } = context.req.valid('param'); const { userId } = getUser({ context }); const organizationsRepository = createOrganizationsRepository({ db }); @@ -111,8 +117,11 @@ function setupRejectInvitationRoute({ app, db }: RouteDefinitionContext) { app.post( '/api/invitations/:invitationId/reject', requireAuthentication(), + validateParams(z.object({ + invitationId: invitationIdSchema, + })), async (context) => { - const { invitationId } = context.req.param(); + const { invitationId } = context.req.valid('param'); const { userId } = getUser({ context }); const organizationsRepository = createOrganizationsRepository({ db }); @@ -146,8 +155,11 @@ function setupCancelInvitationRoute({ app, db }: RouteDefinitionContext) { app.post( '/api/invitations/:invitationId/cancel', requireAuthentication(), + validateParams(z.object({ + invitationId: invitationIdSchema, + })), async (context) => { - const { invitationId } = context.req.param(); + const { invitationId } = context.req.valid('param'); const { userId } = getUser({ context }); const organizationsRepository = createOrganizationsRepository({ db }); @@ -179,8 +191,11 @@ function setupResendInvitationRoute({ app, db, config, emailsServices }: RouteDe app.post( '/api/invitations/:invitationId/resend', requireAuthentication(), + validateParams(z.object({ + invitationId: invitationIdSchema, + })), async (context) => { - const { invitationId } = context.req.param(); + const { invitationId } = context.req.valid('param'); const { userId } = getUser({ context }); const organizationsRepository = createOrganizationsRepository({ db }); diff --git a/apps/papra-server/src/modules/organizations/organization.schemas.ts b/apps/papra-server/src/modules/organizations/organization.schemas.ts index 8b11dd6..e061dda 100644 --- a/apps/papra-server/src/modules/organizations/organization.schemas.ts +++ b/apps/papra-server/src/modules/organizations/organization.schemas.ts @@ -1,5 +1,6 @@ import { z } from 'zod'; -import { ORGANIZATION_ID_REGEX, ORGANIZATION_MEMBER_ID_REGEX } from './organizations.constants'; +import { ORGANIZATION_ID_REGEX, ORGANIZATION_INVITATION_ID_REGEX, ORGANIZATION_MEMBER_ID_REGEX } from './organizations.constants'; export const organizationIdSchema = z.string().regex(ORGANIZATION_ID_REGEX); export const memberIdSchema = z.string().regex(ORGANIZATION_MEMBER_ID_REGEX); +export const invitationIdSchema = z.string().regex(ORGANIZATION_INVITATION_ID_REGEX); diff --git a/apps/papra-server/src/modules/organizations/organizations.constants.ts b/apps/papra-server/src/modules/organizations/organizations.constants.ts index 0436e08..eee5952 100644 --- a/apps/papra-server/src/modules/organizations/organizations.constants.ts +++ b/apps/papra-server/src/modules/organizations/organizations.constants.ts @@ -6,6 +6,9 @@ export const ORGANIZATION_ID_REGEX = createPrefixedIdRegex({ prefix: ORGANIZATIO export const ORGANIZATION_MEMBER_ID_PREFIX = 'org_mem'; export const ORGANIZATION_MEMBER_ID_REGEX = createPrefixedIdRegex({ prefix: ORGANIZATION_MEMBER_ID_PREFIX }); +export const ORGANIZATION_INVITATION_ID_PREFIX = 'org_inv'; +export const ORGANIZATION_INVITATION_ID_REGEX = createPrefixedIdRegex({ prefix: ORGANIZATION_INVITATION_ID_PREFIX }); + export const ORGANIZATION_ROLES = { MEMBER: 'member', OWNER: 'owner', diff --git a/apps/papra-server/src/modules/organizations/organizations.repository.models.ts b/apps/papra-server/src/modules/organizations/organizations.repository.models.ts index 633d0f1..7f9bad1 100644 --- a/apps/papra-server/src/modules/organizations/organizations.repository.models.ts +++ b/apps/papra-server/src/modules/organizations/organizations.repository.models.ts @@ -11,7 +11,7 @@ export function ensureInvitationStatus({ invitation, now = new Date() }: { invit return invitation; } - if (invitation.expiresAt && isAfter(invitation.expiresAt, now)) { + if (isAfter(invitation.expiresAt, now)) { return invitation; } diff --git a/apps/papra-server/src/modules/organizations/organizations.repository.ts b/apps/papra-server/src/modules/organizations/organizations.repository.ts index f0d9ffb..32053c4 100644 --- a/apps/papra-server/src/modules/organizations/organizations.repository.ts +++ b/apps/papra-server/src/modules/organizations/organizations.repository.ts @@ -7,6 +7,7 @@ import { omit } from 'lodash-es'; import { omitUndefined } from '../shared/utils'; import { usersTable } from '../users/users.table'; import { ORGANIZATION_INVITATION_STATUS, ORGANIZATION_ROLES } from './organizations.constants'; +import { createOrganizationNotFoundError } from './organizations.errors'; import { ensureInvitationStatus } from './organizations.repository.models'; import { organizationInvitationsTable, organizationMembersTable, organizationsTable } from './organizations.table'; @@ -49,6 +50,12 @@ export function createOrganizationsRepository({ db }: { db: Database }) { async function saveOrganization({ organization: organizationToInsert, db }: { organization: DbInsertableOrganization; db: Database }) { const [organization] = await db.insert(organizationsTable).values(organizationToInsert).returning(); + if (!organization) { + // This should never happen, as the database should always return the inserted organization + // guard for type safety + throw new Error('Failed to save organization'); + } + return { organization }; } @@ -110,7 +117,7 @@ async function getOrganizationById({ organizationId, db }: { organizationId: str } async function getUserOwnedOrganizationCount({ userId, db }: { userId: string; db: Database }) { - const [{ organizationCount }] = await db + const [record] = await db .select({ organizationCount: count(organizationMembersTable.id), }) @@ -122,13 +129,19 @@ async function getUserOwnedOrganizationCount({ userId, db }: { userId: string; d ), ); + if (!record) { + throw createOrganizationNotFoundError(); + } + + const { organizationCount } = record; + return { organizationCount, }; } async function getOrganizationOwner({ organizationId, db }: { organizationId: string; db: Database }) { - const [{ organizationOwner }] = await db + const [record] = await db .select({ organizationOwner: getTableColumns(usersTable), }) @@ -141,11 +154,17 @@ async function getOrganizationOwner({ organizationId, db }: { organizationId: st ), ); + if (!record) { + throw createOrganizationNotFoundError(); + } + + const { organizationOwner } = record; + return { organizationOwner }; } async function getOrganizationMembersCount({ organizationId, db }: { organizationId: string; db: Database }) { - const [{ membersCount }] = await db + const [record] = await db .select({ membersCount: count(organizationMembersTable.id), }) @@ -154,6 +173,12 @@ async function getOrganizationMembersCount({ organizationId, db }: { organizatio eq(organizationMembersTable.organizationId, organizationId), ); + if (!record) { + throw createOrganizationNotFoundError(); + } + + const { membersCount } = record; + return { membersCount, }; @@ -268,7 +293,7 @@ async function saveOrganizationInvitation({ } async function getTodayUserInvitationCount({ userId, db, now = new Date() }: { userId: string; db: Database; now?: Date }) { - const [{ userInvitationCount }] = await db + const [record] = await db .select({ userInvitationCount: count(organizationInvitationsTable.id), }) @@ -280,6 +305,12 @@ async function getTodayUserInvitationCount({ userId, db, now = new Date() }: { u ), ); + if (!record) { + throw createOrganizationNotFoundError(); + } + + const { userInvitationCount } = record; + return { userInvitationCount, }; @@ -335,7 +366,7 @@ async function updateOrganizationInvitation({ invitationId, status, expiresAt, d } async function getPendingInvitationsCount({ email, db, now = new Date() }: { email: string; db: Database; now?: Date }) { - const [{ pendingInvitationsCount }] = await db + const [record] = await db .select({ pendingInvitationsCount: count(organizationInvitationsTable.id), }) @@ -349,6 +380,12 @@ async function getPendingInvitationsCount({ email, db, now = new Date() }: { ema ), ); + if (!record) { + throw createOrganizationNotFoundError(); + } + + const { pendingInvitationsCount } = record; + return { pendingInvitationsCount, }; diff --git a/apps/papra-server/src/modules/organizations/organizations.routes.ts b/apps/papra-server/src/modules/organizations/organizations.routes.ts index e09ad63..f86d973 100644 --- a/apps/papra-server/src/modules/organizations/organizations.routes.ts +++ b/apps/papra-server/src/modules/organizations/organizations.routes.ts @@ -10,7 +10,7 @@ import { ORGANIZATION_ROLES } from './organizations.constants'; import { createOrganizationsRepository } from './organizations.repository'; import { checkIfUserCanCreateNewOrganization, createOrganization, ensureUserIsInOrganization, inviteMemberToOrganization, removeMemberFromOrganization, updateOrganizationMemberRole } from './organizations.usecases'; -export async function registerOrganizationsRoutes(context: RouteDefinitionContext) { +export function registerOrganizationsRoutes(context: RouteDefinitionContext) { setupGetOrganizationsRoute(context); setupCreateOrganizationRoute(context); setupGetOrganizationRoute(context); diff --git a/apps/papra-server/src/modules/organizations/organizations.table.ts b/apps/papra-server/src/modules/organizations/organizations.table.ts index def8089..16b4f0a 100644 --- a/apps/papra-server/src/modules/organizations/organizations.table.ts +++ b/apps/papra-server/src/modules/organizations/organizations.table.ts @@ -3,7 +3,7 @@ import type { OrganizationInvitationStatus, OrganizationRole } from './organizat import { integer, sqliteTable, text, unique } from 'drizzle-orm/sqlite-core'; import { createPrimaryKeyField, createTimestampColumns } from '../shared/db/columns.helpers'; import { usersTable } from '../users/users.table'; -import { ORGANIZATION_ID_PREFIX, ORGANIZATION_INVITATION_STATUS, ORGANIZATION_INVITATION_STATUS_LIST, ORGANIZATION_MEMBER_ID_PREFIX, ORGANIZATION_ROLES_LIST } from './organizations.constants'; +import { ORGANIZATION_ID_PREFIX, ORGANIZATION_INVITATION_ID_PREFIX, ORGANIZATION_INVITATION_STATUS, ORGANIZATION_INVITATION_STATUS_LIST, ORGANIZATION_MEMBER_ID_PREFIX, ORGANIZATION_ROLES_LIST } from './organizations.constants'; export const organizationsTable = sqliteTable('organizations', { ...createPrimaryKeyField({ prefix: ORGANIZATION_ID_PREFIX }), @@ -31,7 +31,7 @@ export const organizationMembersTable = sqliteTable('organization_members', { ]); export const organizationInvitationsTable = sqliteTable('organization_invitations', { - ...createPrimaryKeyField({ prefix: 'org_inv' }), + ...createPrimaryKeyField({ prefix: ORGANIZATION_INVITATION_ID_PREFIX }), ...createTimestampColumns(), organizationId: text('organization_id').notNull().references(() => organizationsTable.id, { onDelete: 'cascade', onUpdate: 'cascade' }), diff --git a/apps/papra-server/src/modules/organizations/organizations.usecases.test.ts b/apps/papra-server/src/modules/organizations/organizations.usecases.test.ts index 0d0baf1..355d4bb 100644 --- a/apps/papra-server/src/modules/organizations/organizations.usecases.test.ts +++ b/apps/papra-server/src/modules/organizations/organizations.usecases.test.ts @@ -379,7 +379,7 @@ describe('organizations usecases', () => { const remainingMembers = await db.select().from(organizationMembersTable); expect(remainingMembers.length).to.equal(1); - expect(remainingMembers[0].id).to.equal('member-1'); + expect(remainingMembers[0]?.id).to.equal('member-1'); }); test('a member (not admin nor owner) cannot remove anyone from the organization', async () => { diff --git a/apps/papra-server/src/modules/organizations/organizations.usecases.ts b/apps/papra-server/src/modules/organizations/organizations.usecases.ts index 407d8fe..43671ff 100644 --- a/apps/papra-server/src/modules/organizations/organizations.usecases.ts +++ b/apps/papra-server/src/modules/organizations/organizations.usecases.ts @@ -14,6 +14,7 @@ import { createForbiddenError } from '../app/auth/auth.errors'; import { getOrganizationPlan } from '../plans/plans.usecases'; import { sanitize } from '../shared/html/html'; import { createLogger } from '../shared/logger/logger'; +import { isDefined } from '../shared/utils'; import { ORGANIZATION_INVITATION_STATUS, ORGANIZATION_ROLES } from './organizations.constants'; import { createOrganizationDocumentStorageLimitReachedError, @@ -113,7 +114,7 @@ export async function getOrCreateOrganizationCustomerId({ throw createOrganizationNotFoundError(); } - if (organization.customerId) { + if (isDefined(organization.customerId)) { return { customerId: organization.customerId }; } diff --git a/apps/papra-server/src/modules/plans/plans.repository.test.ts b/apps/papra-server/src/modules/plans/plans.repository.test.ts index e7bdba9..6b02a93 100644 --- a/apps/papra-server/src/modules/plans/plans.repository.test.ts +++ b/apps/papra-server/src/modules/plans/plans.repository.test.ts @@ -29,7 +29,7 @@ describe('plans repository', () => { const { organizationPlans } = getOrganizationPlansRecords({ config }); - expect(organizationPlans[FREE_PLAN_ID].limits).to.deep.equal({ + expect(organizationPlans[FREE_PLAN_ID]!.limits).to.deep.equal({ maxDocumentStorageBytes: Number.POSITIVE_INFINITY, maxIntakeEmailsCount: Number.POSITIVE_INFINITY, maxOrganizationsMembersCount: Number.POSITIVE_INFINITY, diff --git a/apps/papra-server/src/modules/roles/roles.models.test.ts b/apps/papra-server/src/modules/roles/roles.models.test.ts deleted file mode 100644 index 8d3a2f5..0000000 --- a/apps/papra-server/src/modules/roles/roles.models.test.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { describe, expect, test } from 'vitest'; -import { areSomeRolesInJwtPayload } from './roles.models'; - -describe('roles models', () => { - describe('areSomeRolesInJwtPayload', () => { - test('check if at least one roles in the jwtPayload match at least one of the expected roles', () => { - expect(areSomeRolesInJwtPayload({ - roles: ['admin'], - jwtPayload: { - roles: ['admin', 'user'], - }, - })).to.eql(true); - - expect(areSomeRolesInJwtPayload({ - roles: ['admin'], - jwtPayload: { - roles: [], - }, - })).to.eql(false); - }); - - test('when the roles field in the jwtPayload is not a string array, it should return false', () => { - expect(areSomeRolesInJwtPayload({ - roles: ['admin'], - jwtPayload: { - roles: 'admin', - }, - })).to.eql(false); - - expect(areSomeRolesInJwtPayload({ - roles: ['admin'], - jwtPayload: { - roles: undefined, - }, - })).to.eql(false); - - expect(areSomeRolesInJwtPayload({ - roles: ['admin'], - jwtPayload: { - roles: ['admin', 123], - }, - })).to.eql(false); - - expect(areSomeRolesInJwtPayload({ - roles: ['admin'], - jwtPayload: {}, - })).to.eql(false); - - expect(areSomeRolesInJwtPayload({ - roles: ['admin'], - jwtPayload: undefined, - })).to.eql(false); - }); - }); -}); diff --git a/apps/papra-server/src/modules/roles/roles.models.ts b/apps/papra-server/src/modules/roles/roles.models.ts deleted file mode 100644 index a25ebd4..0000000 --- a/apps/papra-server/src/modules/roles/roles.models.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { get, isArray, isString } from 'lodash-es'; - -export function areSomeRolesInJwtPayload({ roles, jwtPayload }: { roles: string[]; jwtPayload?: Record }) { - const rolesInJwt = get(jwtPayload, 'roles'); - - if (!rolesInJwt) { - return false; - } - - if (!isArray(rolesInJwt) || !rolesInJwt.every(isString)) { - return false; - } - - return rolesInJwt.some(role => roles.includes(role)); -} diff --git a/apps/papra-server/src/modules/shared/async/defer.test-utils.ts b/apps/papra-server/src/modules/shared/async/defer.test-utils.ts index 80a5207..e3d1031 100644 --- a/apps/papra-server/src/modules/shared/async/defer.test-utils.ts +++ b/apps/papra-server/src/modules/shared/async/defer.test-utils.ts @@ -1 +1 @@ -export const nextTick = () => new Promise(resolve => setImmediate(resolve)); +export const nextTick = async () => new Promise(resolve => setImmediate(resolve)); diff --git a/apps/papra-server/src/modules/shared/async/defer.ts b/apps/papra-server/src/modules/shared/async/defer.ts index 47ef8e5..9e5b334 100644 --- a/apps/papra-server/src/modules/shared/async/defer.ts +++ b/apps/papra-server/src/modules/shared/async/defer.ts @@ -13,5 +13,5 @@ export function safelyDefer(fn: () => Promise, { logger = createLogger({ n } export function createDeferable(fn: (...args: Args) => Promise) { - return (...args: Args) => safelyDefer(() => fn(...args)); + return (...args: Args) => safelyDefer(async () => fn(...args)); } diff --git a/apps/papra-server/src/modules/shared/errors/errors.test.ts b/apps/papra-server/src/modules/shared/errors/errors.test.ts index 3759eb2..9159af1 100644 --- a/apps/papra-server/src/modules/shared/errors/errors.test.ts +++ b/apps/papra-server/src/modules/shared/errors/errors.test.ts @@ -19,6 +19,7 @@ describe('errors', () => { expect(error.message).to.eql('foo'); expect(error.code).to.eql('bar'); expect(error.statusCode).to.eql(500); + expect(error.isInternal).to.eql(false); }); test('accepts an optional cause property to attach the original error that caused the custom error', () => { diff --git a/apps/papra-server/src/modules/shared/errors/errors.ts b/apps/papra-server/src/modules/shared/errors/errors.ts index 63fa44a..4a06dc8 100644 --- a/apps/papra-server/src/modules/shared/errors/errors.ts +++ b/apps/papra-server/src/modules/shared/errors/errors.ts @@ -16,9 +16,9 @@ class CustomError extends Error { cause?: Error | null; statusCode: ContentfulStatusCode; isCustomError = true; - isInternal?: boolean; + isInternal: boolean = false; - constructor({ message, code, cause, statusCode, isInternal }: ErrorOptions) { + constructor({ message, code, cause, statusCode, isInternal = false }: ErrorOptions) { super(message); this.code = code; diff --git a/apps/papra-server/src/modules/shared/fs/fs.services.ts b/apps/papra-server/src/modules/shared/fs/fs.services.ts index b26ead3..a55930b 100644 --- a/apps/papra-server/src/modules/shared/fs/fs.services.ts +++ b/apps/papra-server/src/modules/shared/fs/fs.services.ts @@ -51,7 +51,7 @@ export async function moveFile({ sourceFilePath, destinationFilePath, fs = fsNat } export async function readFile({ filePath, fs = fsNative }: { filePath: string; fs?: FsNative }) { - return await fs.readFile(filePath); + return fs.readFile(filePath); } export async function areFilesContentIdentical({ file1, file2, fs = fsNative }: { file1: string; file2: string; fs?: FsNative }): Promise { diff --git a/apps/papra-server/src/modules/shared/logger/logger.middleware.ts b/apps/papra-server/src/modules/shared/logger/logger.middleware.ts index a9524be..f9a0e09 100644 --- a/apps/papra-server/src/modules/shared/logger/logger.middleware.ts +++ b/apps/papra-server/src/modules/shared/logger/logger.middleware.ts @@ -1,3 +1,4 @@ +import type { Context } from '../../app/server.types'; import { createMiddleware } from 'hono/factory'; import { getHeader } from '../headers/headers.models'; import { generateId } from '../random/ids'; @@ -6,7 +7,7 @@ import { createLogger, wrapWithLoggerContext } from './logger'; const logger = createLogger({ namespace: 'app' }); export function createLoggerMiddleware() { - return createMiddleware(async (context, next) => { + return createMiddleware(async (context: Context, next) => { const requestId = getHeader({ context, name: 'x-request-id' }); await wrapWithLoggerContext( diff --git a/apps/papra-server/src/modules/shared/path.ts b/apps/papra-server/src/modules/shared/path.ts index 74445c1..3cb6a01 100644 --- a/apps/papra-server/src/modules/shared/path.ts +++ b/apps/papra-server/src/modules/shared/path.ts @@ -6,7 +6,7 @@ export const getRootDirPath = memoize(() => process.cwd()); // Working with libsql, file url can be relative, which is not correct according to RFC 8089, which standardizes the `file` scheme // see https://github.com/tursodatabase/libsql-client-ts/blob/ee036574f5c23335c8b2d6d0c0e117cbe14bf376/packages/libsql-core/src/uri.ts export function fileUrlToPath({ fileUrl }: { fileUrl: string }) { - const rawPath = fileUrl.replace(/^file:(\/\/)?/, ''); + const rawPath = fileUrl.replace(/^file:(?:\/\/)?/, ''); return decodeURIComponent(rawPath); } diff --git a/apps/papra-server/src/modules/shared/random/ids.ts b/apps/papra-server/src/modules/shared/random/ids.ts index ccd0ee0..8e6aca7 100644 --- a/apps/papra-server/src/modules/shared/random/ids.ts +++ b/apps/papra-server/src/modules/shared/random/ids.ts @@ -6,7 +6,7 @@ const createId = init({ length: ID_RANDOM_PART_LENGTH }); export function generateId({ prefix, getRandomPart = createId }: { prefix?: string; getRandomPart?: () => string } = {}) { const id = getRandomPart(); - return prefix ? `${prefix}_${id}` : id; + return prefix !== undefined ? `${prefix}_${id}` : id; } export function createPrefixedIdRegex({ prefix }: { prefix: string }) { diff --git a/apps/papra-server/src/modules/shared/streams/readable-stream.ts b/apps/papra-server/src/modules/shared/streams/readable-stream.ts index cb368c3..c8ec095 100644 --- a/apps/papra-server/src/modules/shared/streams/readable-stream.ts +++ b/apps/papra-server/src/modules/shared/streams/readable-stream.ts @@ -1,3 +1,3 @@ export async function collectReadableStreamToString({ stream }: { stream: ReadableStream }) { - return await new Response(stream).text(); + return new Response(stream).text(); } diff --git a/apps/papra-server/src/modules/shared/utils.test.ts b/apps/papra-server/src/modules/shared/utils.test.ts index f66b982..78c66d7 100644 --- a/apps/papra-server/src/modules/shared/utils.test.ts +++ b/apps/papra-server/src/modules/shared/utils.test.ts @@ -1,5 +1,5 @@ import { describe, expect, test } from 'vitest'; -import { omitUndefined } from './utils'; +import { isDefined, isNil, omitUndefined } from './utils'; describe('utils', () => { describe('omitUndefined', () => { @@ -22,4 +22,29 @@ describe('utils', () => { }); }); }); + + describe('isNil', () => { + test('a value is considered nil if it is either undefined or null', () => { + expect(isNil(undefined)).toBe(true); + expect(isNil(null)).toBe(true); + + expect(isNil(0)).toBe(false); + expect(isNil('')).toBe(false); + expect(isNil(false)).toBe(false); + expect(isNil({})).toBe(false); + expect(isNil([])).toBe(false); + }); + }); + + describe('isDefined', () => { + test('a value is considered defined if it is not undefined or null', () => { + expect(isDefined(undefined)).toBe(false); + expect(isDefined(null)).toBe(false); + + expect(isDefined(0)).toBe(true); + expect(isDefined('')).toBe(true); + expect(isDefined(false)).toBe(true); + expect(isDefined({})).toBe(true); + }); + }); }); diff --git a/apps/papra-server/src/modules/shared/utils.ts b/apps/papra-server/src/modules/shared/utils.ts index ad0fc73..9af2d50 100644 --- a/apps/papra-server/src/modules/shared/utils.ts +++ b/apps/papra-server/src/modules/shared/utils.ts @@ -7,3 +7,11 @@ type OmitUndefined = { export function omitUndefined>(obj: T): OmitUndefined { return omitBy(obj, isUndefined) as OmitUndefined; } + +export function isNil(value: unknown): value is undefined | null { + return value === undefined || value === null; +} + +export function isDefined(value: T): value is Exclude { + return !isNil(value); +} diff --git a/apps/papra-server/src/modules/shared/validation/validation.ts b/apps/papra-server/src/modules/shared/validation/validation.ts index 2e3458f..f0837d3 100644 --- a/apps/papra-server/src/modules/shared/validation/validation.ts +++ b/apps/papra-server/src/modules/shared/validation/validation.ts @@ -17,11 +17,13 @@ function buildValidator({ target, error return (schema: Schema, { allowAdditionalFields = false }: { allowAdditionalFields?: boolean } = {}) => { return validator(target, (value, context) => { // @ts-expect-error try to enforce strict mode - const refinedSchema = allowAdditionalFields ? schema : (schema.strict?.() ?? schema); + // eslint-disable-next-line ts/no-unsafe-assignment, ts/no-unsafe-call + const refinedSchema: Schema = allowAdditionalFields ? schema : (schema.strict?.() ?? schema); const result = refinedSchema.safeParse(value); if (result.success) { + // eslint-disable-next-line ts/no-unsafe-return return result.data as z.infer; } diff --git a/apps/papra-server/src/modules/subscriptions/subscriptions.models.test.ts b/apps/papra-server/src/modules/subscriptions/subscriptions.models.test.ts index 6eafa79..a34220d 100644 --- a/apps/papra-server/src/modules/subscriptions/subscriptions.models.test.ts +++ b/apps/papra-server/src/modules/subscriptions/subscriptions.models.test.ts @@ -1,5 +1,5 @@ import { describe, expect, test } from 'vitest'; -import { coerceStripeTimestampToDate } from './subscriptions.models'; +import { coerceStripeTimestampToDate, isSignatureHeaderFormatValid } from './subscriptions.models'; describe('subscriptions models', () => { describe('coerceStripeTimestampToDate', () => { @@ -10,4 +10,13 @@ describe('subscriptions models', () => { expect(date).to.deep.equal(new Date('2024-05-19T20:26:23.000Z')); }); }); + + describe('isSignatureHeaderFormatValid', () => { + test('the signature value should be a non empty string', () => { + expect(isSignatureHeaderFormatValid(undefined)).toBe(false); + expect(isSignatureHeaderFormatValid('')).toBe(false); + + expect(isSignatureHeaderFormatValid('v1_1234567890')).toBe(true); + }); + }); }); diff --git a/apps/papra-server/src/modules/subscriptions/subscriptions.models.ts b/apps/papra-server/src/modules/subscriptions/subscriptions.models.ts index a128360..9ef5df2 100644 --- a/apps/papra-server/src/modules/subscriptions/subscriptions.models.ts +++ b/apps/papra-server/src/modules/subscriptions/subscriptions.models.ts @@ -1,3 +1,13 @@ +import { isNil } from '../shared/utils'; + export function coerceStripeTimestampToDate(timestamp: number) { return new Date(timestamp * 1000); } + +export function isSignatureHeaderFormatValid(signature: string | undefined): signature is string { + if (isNil(signature)) { + return false; + } + + return typeof signature === 'string' && signature.length > 0; +} diff --git a/apps/papra-server/src/modules/subscriptions/subscriptions.routes.ts b/apps/papra-server/src/modules/subscriptions/subscriptions.routes.ts index cf2c3dd..d0819ef 100644 --- a/apps/papra-server/src/modules/subscriptions/subscriptions.routes.ts +++ b/apps/papra-server/src/modules/subscriptions/subscriptions.routes.ts @@ -13,8 +13,10 @@ import { getOrganizationPlan } from '../plans/plans.usecases'; import { createError } from '../shared/errors/errors'; import { getHeader } from '../shared/headers/headers.models'; import { createLogger } from '../shared/logger/logger'; +import { isNil } from '../shared/utils'; import { validateJsonBody, validateParams } from '../shared/validation/validation'; import { createInvalidWebhookPayloadError, createOrganizationAlreadyHasSubscriptionError } from './subscriptions.errors'; +import { isSignatureHeaderFormatValid } from './subscriptions.models'; import { createSubscriptionsRepository } from './subscriptions.repository'; import { handleStripeWebhookEvent } from './subscriptions.usecases'; @@ -31,7 +33,7 @@ function setupStripeWebhookRoute({ app, config, db, subscriptionsServices }: Rou app.post('/api/stripe/webhook', async (context) => { const signature = getHeader({ context, name: 'stripe-signature' }); - if (!signature) { + if (!isSignatureHeaderFormatValid(signature)) { throw createInvalidWebhookPayloadError(); } @@ -59,7 +61,7 @@ function setupStripeWebhookRoute({ app, config, db, subscriptionsServices }: Rou }); } -async function setupCreateCheckoutSessionRoute({ app, config, db, subscriptionsServices }: RouteDefinitionContext) { +function setupCreateCheckoutSessionRoute({ app, config, db, subscriptionsServices }: RouteDefinitionContext) { app.post( '/api/organizations/:organizationId/checkout-session', requireAuthentication(), @@ -99,7 +101,7 @@ async function setupCreateCheckoutSessionRoute({ app, config, db, subscriptionsS const { organizationPlan: organizationPlanToSubscribeTo } = await plansRepository.getOrganizationPlanById({ planId }); - if (!organizationPlanToSubscribeTo.priceId) { + if (isNil(organizationPlanToSubscribeTo.priceId)) { // Very unlikely to happen, as only the free plan does not have a price ID, and we check for the plans in the route validation // but for type safety, we assert that the price ID is set throw createError({ diff --git a/apps/papra-server/src/modules/subscriptions/subscriptions.services.ts b/apps/papra-server/src/modules/subscriptions/subscriptions.services.ts index 874ae59..d298a44 100644 --- a/apps/papra-server/src/modules/subscriptions/subscriptions.services.ts +++ b/apps/papra-server/src/modules/subscriptions/subscriptions.services.ts @@ -1,3 +1,4 @@ +import type { Buffer } from 'node:buffer'; import type { Config } from '../config/config.types'; import { buildUrl, injectArguments } from '@corentinth/chisels'; import Stripe from 'stripe'; @@ -69,7 +70,7 @@ export async function createCheckoutUrl({ return { checkoutUrl: session.url }; } -async function parseWebhookEvent({ stripeClient, payload, signature, config }: { stripeClient: Stripe; payload: any; signature: string; config: Config }) { +async function parseWebhookEvent({ stripeClient, payload, signature, config }: { stripeClient: Stripe; payload: string | Buffer; signature: string; config: Config }) { const event = await stripeClient.webhooks.constructEventAsync(payload, signature, config.subscriptions.stripeWebhookSecret); return { event }; diff --git a/apps/papra-server/src/modules/subscriptions/subscriptions.usecases.ts b/apps/papra-server/src/modules/subscriptions/subscriptions.usecases.ts index c6d9803..c6e9a4a 100644 --- a/apps/papra-server/src/modules/subscriptions/subscriptions.usecases.ts +++ b/apps/papra-server/src/modules/subscriptions/subscriptions.usecases.ts @@ -3,6 +3,7 @@ import type { PlansRepository } from '../plans/plans.repository'; import type { SubscriptionsRepository } from './subscriptions.repository'; import { get } from 'lodash-es'; import { createOrganizationNotFoundError } from '../organizations/organizations.errors'; +import { isNil } from '../shared/utils'; import { coerceStripeTimestampToDate } from './subscriptions.models'; export async function handleStripeWebhookEvent({ @@ -23,7 +24,7 @@ export async function handleStripeWebhookEvent({ const cancelAtPeriodEnd = get(event, 'data.object.cancel_at_period_end'); const status = get(event, 'data.object.status'); - if (!organizationId) { + if (isNil(organizationId)) { throw createOrganizationNotFoundError(); } @@ -52,7 +53,7 @@ export async function handleStripeWebhookEvent({ const cancelAtPeriodEnd = get(event, 'data.object.cancel_at_period_end'); const status = get(event, 'data.object.status'); - if (!organizationId) { + if (isNil(organizationId)) { throw createOrganizationNotFoundError(); } diff --git a/apps/papra-server/src/modules/tagging-rules/tagging-rules.models.ts b/apps/papra-server/src/modules/tagging-rules/tagging-rules.models.ts index fa147e9..56e846a 100644 --- a/apps/papra-server/src/modules/tagging-rules/tagging-rules.models.ts +++ b/apps/papra-server/src/modules/tagging-rules/tagging-rules.models.ts @@ -2,7 +2,7 @@ import type { Document } from '../documents/documents.types'; import { get } from 'lodash-es'; export function getDocumentFieldValue({ document, field }: { document: Document; field: string }) { - const fieldValue = get(document, field); + const fieldValue: unknown = get(document, field); - return { fieldValue }; + return { fieldValue: String(fieldValue ?? '') }; } diff --git a/apps/papra-server/src/modules/tagging-rules/tagging-rules.repository.ts b/apps/papra-server/src/modules/tagging-rules/tagging-rules.repository.ts index 438f77c..3ae2d5f 100644 --- a/apps/papra-server/src/modules/tagging-rules/tagging-rules.repository.ts +++ b/apps/papra-server/src/modules/tagging-rules/tagging-rules.repository.ts @@ -69,6 +69,12 @@ async function getOrganizationEnabledTaggingRules({ organizationId, db }: { orga async function createTaggingRule({ taggingRule, db }: { taggingRule: DbInsertableTaggingRule; db: Database }) { const [createdTaggingRule] = await db.insert(taggingRulesTable).values(taggingRule).returning(); + if (!createdTaggingRule) { + // Very unlikely to happen as the query will throw an error if the tagging rule is not created + // it's for type safety + throw new Error('Failed to create tagging rule'); + } + return { taggingRule: createdTaggingRule }; } diff --git a/apps/papra-server/src/modules/tagging-rules/tagging-rules.usecases.test.ts b/apps/papra-server/src/modules/tagging-rules/tagging-rules.usecases.test.ts index dbf24cb..686ba7a 100644 --- a/apps/papra-server/src/modules/tagging-rules/tagging-rules.usecases.test.ts +++ b/apps/papra-server/src/modules/tagging-rules/tagging-rules.usecases.test.ts @@ -3,6 +3,7 @@ import { describe, expect, test } from 'vitest'; import { createInMemoryDatabase } from '../app/database/database.test-utils'; import { documentsTable } from '../documents/documents.table'; import { createTestLogger } from '../shared/logger/logger.test-utils'; +import { isNil } from '../shared/utils'; import { createTagsRepository } from '../tags/tags.repository'; import { documentsTagsTable } from '../tags/tags.table'; import { createTaggingRulesRepository } from './tagging-rules.repository'; @@ -25,6 +26,11 @@ describe('tagging-rules usecases', () => { const [document] = await db.select().from(documentsTable).where(eq(documentsTable.id, 'doc_1')); + if (isNil(document)) { + // type safety + throw new Error('Document not found'); + } + const taggingRulesRepository = createTaggingRulesRepository({ db }); const tagsRepository = createTagsRepository({ db }); @@ -60,6 +66,11 @@ describe('tagging-rules usecases', () => { const [document] = await db.select().from(documentsTable).where(eq(documentsTable.id, 'doc_1')); + if (isNil(document)) { + // type safety + throw new Error('Document not found'); + } + const taggingRulesRepository = createTaggingRulesRepository({ db }); const tagsRepository = createTagsRepository({ db }); @@ -78,6 +89,11 @@ describe('tagging-rules usecases', () => { const [document] = await db.select().from(documentsTable).where(eq(documentsTable.id, 'doc_1')); + if (isNil(document)) { + // type safety + throw new Error('Document not found'); + } + const taggingRulesRepository = createTaggingRulesRepository({ db }); const tagsRepository = createTagsRepository({ db }); diff --git a/apps/papra-server/src/modules/tagging-rules/tagging-rules.usecases.ts b/apps/papra-server/src/modules/tagging-rules/tagging-rules.usecases.ts index d65bf3c..d5a5bc3 100644 --- a/apps/papra-server/src/modules/tagging-rules/tagging-rules.usecases.ts +++ b/apps/papra-server/src/modules/tagging-rules/tagging-rules.usecases.ts @@ -85,7 +85,7 @@ export async function applyTaggingRules({ const tagIdsToApply: string[] = uniq(taggingRulesToApplyActions.flatMap(taggingRule => taggingRule.actions.map(action => action.tagId))); const appliedTagIds = await Promise.all(tagIdsToApply.map(async (tagId) => { - const [, error] = await safely(() => tagsRepository.addTagToDocument({ tagId, documentId: document.id })); + const [, error] = await safely(async () => tagsRepository.addTagToDocument({ tagId, documentId: document.id })); if (error) { logger.error({ error, tagId, documentId: document.id }, 'Failed to add tag to document'); diff --git a/apps/papra-server/src/modules/tags/tags.repository.test.ts b/apps/papra-server/src/modules/tags/tags.repository.test.ts index d64c689..3b1d130 100644 --- a/apps/papra-server/src/modules/tags/tags.repository.test.ts +++ b/apps/papra-server/src/modules/tags/tags.repository.test.ts @@ -1,6 +1,7 @@ import { describe, expect, test } from 'vitest'; import { createInMemoryDatabase } from '../app/database/database.test-utils'; import { ORGANIZATION_ROLES } from '../organizations/organizations.constants'; +import { isNil } from '../shared/utils'; import { createDocumentAlreadyHasTagError, createTagAlreadyExistsError } from './tags.errors'; import { createTagsRepository } from './tags.repository'; @@ -17,6 +18,11 @@ describe('tags repository', () => { tag: { organizationId: 'organization-1', name: 'Tag 1', color: '#aa0000' }, }); + if (isNil(tag1)) { + // type safety + throw new Error('Tag 1 not found'); + } + expect(tag1).to.include({ organizationId: 'organization-1', name: 'Tag 1', diff --git a/apps/papra-server/src/modules/tasks/task-scheduler.ts b/apps/papra-server/src/modules/tasks/task-scheduler.ts index 0963d78..01bd6e5 100644 --- a/apps/papra-server/src/modules/tasks/task-scheduler.ts +++ b/apps/papra-server/src/modules/tasks/task-scheduler.ts @@ -29,12 +29,12 @@ function createTaskScheduler({ const task = cron.schedule( cronSchedule, - () => wrapWithLoggerContext( + async () => wrapWithLoggerContext( { taskId: generateId({ prefix: 'task' }), taskName: taskDefinition.taskName, }, - () => taskDefinition.run({ ...tasksArgs, config }), + async () => taskDefinition.run({ ...tasksArgs, config }), ), { scheduled: false, diff --git a/apps/papra-server/src/modules/tracking/tracking.services.ts b/apps/papra-server/src/modules/tracking/tracking.services.ts index 5b9a2c8..66fe6a7 100644 --- a/apps/papra-server/src/modules/tracking/tracking.services.ts +++ b/apps/papra-server/src/modules/tracking/tracking.services.ts @@ -14,7 +14,7 @@ export type TrackingServices = { export function createDummyTrackingServices(): TrackingServices { return { captureUserEvent: () => {}, - shutdown: () => Promise.resolve(), + shutdown: async () => Promise.resolve(), }; } @@ -37,6 +37,6 @@ export function createTrackingServices({ config }: { config: Config }): Tracking captureUserEvent: ({ userId, event, properties }) => { trackingClient.capture({ distinctId: userId, event, properties }); }, - shutdown: () => trackingClient.shutdown(), + shutdown: async () => trackingClient.shutdown(), }; } diff --git a/apps/papra-server/src/modules/users/users.routes.ts b/apps/papra-server/src/modules/users/users.routes.ts index ad01482..5ef15b8 100644 --- a/apps/papra-server/src/modules/users/users.routes.ts +++ b/apps/papra-server/src/modules/users/users.routes.ts @@ -7,7 +7,7 @@ import { createRolesRepository } from '../roles/roles.repository'; import { validateJsonBody } from '../shared/validation/validation'; import { createUsersRepository } from './users.repository'; -export async function registerUsersRoutes(context: RouteDefinitionContext) { +export function registerUsersRoutes(context: RouteDefinitionContext) { setupGetCurrentUserRoute(context); setupUpdateUserRoute(context); } diff --git a/apps/papra-server/src/modules/webhooks/webhook.repository.ts b/apps/papra-server/src/modules/webhooks/webhook.repository.ts index 41e4e49..9b888bd 100644 --- a/apps/papra-server/src/modules/webhooks/webhook.repository.ts +++ b/apps/papra-server/src/modules/webhooks/webhook.repository.ts @@ -26,7 +26,13 @@ export function createWebhookRepository({ db }: { db: Database }) { async function createOrganizationWebhook({ db, ...webhook }: { db: Database } & { name: string; url: string; secret?: string; enabled?: boolean; events?: EventName[]; organizationId: string; createdBy: string }) { const [createdWebhook] = await db.insert(webhooksTable).values(webhook).returning(); - if (webhook.events?.length) { + if (!createdWebhook) { + // Very unlikely to happen as the query will throw an error if the webhook is not created + // it's for type safety + throw new Error('Failed to create webhook'); + } + + if (webhook.events && webhook.events.length > 0) { await db .insert(webhookEventsTable) .values( @@ -87,6 +93,10 @@ async function getOrganizationWebhookById({ db, webhookId, organizationId }: { d ), ); + if (!records.length) { + return { webhook: undefined }; + } + const [{ webhook } = {}] = records; const events = records.map(record => record.webhookEvents?.eventName); diff --git a/apps/papra-server/src/modules/webhooks/webhook.usecases.ts b/apps/papra-server/src/modules/webhooks/webhook.usecases.ts index fb0702d..163715c 100644 --- a/apps/papra-server/src/modules/webhooks/webhook.usecases.ts +++ b/apps/papra-server/src/modules/webhooks/webhook.usecases.ts @@ -99,8 +99,8 @@ export async function triggerWebhooks({ const limit = pLimit(10); await Promise.all( - webhooks.map(webhook => - limit(() => + webhooks.map(async webhook => + limit(async () => triggerWebhook({ webhook, webhookRepository, now, ...webhookData, logger, triggerWebhookService }), ), ), diff --git a/apps/papra-server/src/scripts/commons/run-script.ts b/apps/papra-server/src/scripts/commons/run-script.ts index 3be4643..852686e 100644 --- a/apps/papra-server/src/scripts/commons/run-script.ts +++ b/apps/papra-server/src/scripts/commons/run-script.ts @@ -15,7 +15,7 @@ async function runScript( ) { const isDryRun = process.argv.includes('--dry-run'); - wrapWithLoggerContext( + await wrapWithLoggerContext( { scriptName, isDryRun, diff --git a/apps/papra-server/src/scripts/migrate-up.script.ts b/apps/papra-server/src/scripts/migrate-up.script.ts index 7b696fb..317c79b 100644 --- a/apps/papra-server/src/scripts/migrate-up.script.ts +++ b/apps/papra-server/src/scripts/migrate-up.script.ts @@ -1,7 +1,7 @@ import { runMigrations } from '../modules/app/database/database.services'; import { runScript } from './commons/run-script'; -runScript( +await runScript( { scriptName: 'migrate-up' }, async ({ db }) => { // Drizzle kit config don't support encryption yet so we cannot use npx drizzle-kit migrate diff --git a/apps/papra-server/src/scripts/send-intake-email.script.ts b/apps/papra-server/src/scripts/send-intake-email.script.ts index c5c8f2c..7cbf299 100644 --- a/apps/papra-server/src/scripts/send-intake-email.script.ts +++ b/apps/papra-server/src/scripts/send-intake-email.script.ts @@ -3,7 +3,7 @@ import { triggerWebhook } from '@owlrelay/webhook'; import { INTAKE_EMAILS_INGEST_ROUTE } from '../modules/intake-emails/intake-emails.constants'; import { runScript } from './commons/run-script'; -runScript( +await runScript( { scriptName: 'simulate-intake-email' }, async ({ config }) => { const { baseUrl } = config.server; diff --git a/apps/papra-server/tsconfig.json b/apps/papra-server/tsconfig.json index bbfc7ac..01c41a5 100644 --- a/apps/papra-server/tsconfig.json +++ b/apps/papra-server/tsconfig.json @@ -9,6 +9,7 @@ "module": "ESNext", "moduleResolution": "Bundler", "strict": true, + "noUncheckedIndexedAccess": true, "allowSyntheticDefaultImports": true, "skipLibCheck": true } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8962240..b50e4bf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,30 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +catalogs: + default: + '@antfu/eslint-config': + specifier: ^4.16.2 + version: 4.16.2 + '@types/node': + specifier: ^22.15.21 + version: 22.16.0 + '@vitest/coverage-v8': + specifier: ^3.0.2 + version: 3.2.4 + better-auth: + specifier: ^1.2.8 + version: 1.2.12 + eslint: + specifier: ^9.30.1 + version: 9.30.1 + typescript: + specifier: ^5.6.2 + version: 5.8.3 + vitest: + specifier: ^3.0.5 + version: 3.2.4 + importers: .: @@ -19,13 +43,13 @@ importers: dependencies: '@astrojs/solid-js': specifier: ^5.1.0 - version: 5.1.0(@types/node@22.15.21)(jiti@2.4.2)(solid-js@1.9.7)(tsx@4.20.3)(yaml@2.8.0) + version: 5.1.0(@types/node@24.0.10)(jiti@2.4.2)(solid-js@1.9.7)(tsx@4.20.3)(yaml@2.8.0) '@astrojs/starlight': specifier: ^0.34.3 - version: 0.34.3(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@22.15.21)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0)) + version: 0.34.3(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@24.0.10)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0)) astro: specifier: ^5.8.0 - version: 5.8.0(@azure/storage-blob@12.27.0)(@types/node@22.15.21)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) + version: 5.8.0(@azure/storage-blob@12.27.0)(@types/node@24.0.10)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) sharp: specifier: ^0.32.5 version: 0.32.6 @@ -34,16 +58,16 @@ importers: version: 3.4.2 starlight-links-validator: specifier: ^0.16.0 - version: 0.16.0(@astrojs/starlight@0.34.3(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@22.15.21)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))) + version: 0.16.0(@astrojs/starlight@0.34.3(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@24.0.10)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))) starlight-theme-rapide: specifier: ^0.5.0 - version: 0.5.1(@astrojs/starlight@0.34.3(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@22.15.21)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))) + version: 0.5.1(@astrojs/starlight@0.34.3(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@24.0.10)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))) tailwind-merge: specifier: ^2.6.0 version: 2.6.0 unocss-preset-animations: specifier: ^1.2.1 - version: 1.2.1(unocss@0.65.0-beta.2(postcss@8.5.3)(rollup@4.39.0)(vite@6.3.4(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3))) + version: 1.2.1(unocss@0.65.0-beta.2(postcss@8.5.3)(rollup@4.39.0)(vite@6.3.4(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3))) yaml: specifier: ^2.8.0 version: 2.8.0 @@ -53,7 +77,7 @@ importers: devDependencies: '@antfu/eslint-config': specifier: ^3.13.0 - version: 3.16.0(@typescript-eslint/utils@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jiti@2.4.2)(jsdom@26.0.0)(tsx@4.20.3)(yaml@2.8.0)) + version: 3.16.0(@typescript-eslint/utils@8.35.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.0.10)(jsdom@26.0.0)) '@iconify-json/tabler': specifier: ^1.1.120 version: 1.2.18 @@ -83,7 +107,7 @@ importers: version: 5.8.3 unocss: specifier: 0.65.0-beta.2 - version: 0.65.0-beta.2(postcss@8.5.3)(rollup@4.39.0)(vite@6.3.4(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3)) + version: 0.65.0-beta.2(postcss@8.5.3)(rollup@4.39.0)(vite@6.3.4(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3)) apps/papra-client: dependencies: @@ -119,7 +143,7 @@ importers: version: 0.64.1 better-auth: specifier: 'catalog:' - version: 1.2.8 + version: 1.2.12 class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -158,7 +182,7 @@ importers: version: 5.7.1 unocss-preset-animations: specifier: ^1.2.1 - version: 1.2.1(unocss@0.65.0-beta.2(postcss@8.5.6)(rollup@4.39.0)(vite@5.4.19(@types/node@22.15.21))(vue@3.5.13(typescript@5.8.3))) + version: 1.2.1(unocss@0.65.0-beta.2(postcss@8.5.6)(rollup@4.39.0)(vite@5.4.19(@types/node@22.16.0))(vue@3.5.13(typescript@5.8.3))) unstorage: specifier: ^1.16.0 version: 1.16.0(@azure/storage-blob@12.27.0)(idb-keyval@6.2.1) @@ -168,7 +192,7 @@ importers: devDependencies: '@antfu/eslint-config': specifier: 'catalog:' - version: 4.13.1(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@25.0.1(canvas@2.11.2))) + version: 4.16.2(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(jsdom@25.0.1(canvas@2.11.2))) '@iconify-json/tabler': specifier: ^1.2.19 version: 1.2.19 @@ -180,10 +204,10 @@ importers: version: 4.17.12 '@types/node': specifier: 'catalog:' - version: 22.15.21 + version: 22.16.0 eslint: specifier: 'catalog:' - version: 9.27.0(jiti@2.4.2) + version: 9.30.1(jiti@2.4.2) jsdom: specifier: ^25.0.1 version: 25.0.1(canvas@2.11.2) @@ -198,16 +222,16 @@ importers: version: 5.8.3 unocss: specifier: 0.65.0-beta.2 - version: 0.65.0-beta.2(postcss@8.5.6)(rollup@4.39.0)(vite@5.4.19(@types/node@22.15.21))(vue@3.5.13(typescript@5.8.3)) + version: 0.65.0-beta.2(postcss@8.5.6)(rollup@4.39.0)(vite@5.4.19(@types/node@22.16.0))(vue@3.5.13(typescript@5.8.3)) vite: specifier: ^5.4.19 - version: 5.4.19(@types/node@22.15.21) + version: 5.4.19(@types/node@22.16.0) vite-plugin-solid: specifier: ^2.11.7 - version: 2.11.7(solid-js@1.9.7)(vite@5.4.19(@types/node@22.15.21)) + version: 2.11.7(solid-js@1.9.7)(vite@5.4.19(@types/node@22.16.0)) vitest: specifier: 'catalog:' - version: 3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@25.0.1(canvas@2.11.2)) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(jsdom@25.0.1(canvas@2.11.2)) yaml: specifier: ^2.8.0 version: 2.8.0 @@ -328,7 +352,7 @@ importers: devDependencies: '@antfu/eslint-config': specifier: 'catalog:' - version: 4.13.1(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@26.0.0)) + version: 4.16.2(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@26.0.0)) '@crowlog/pretty': specifier: ^1.2.1 version: 1.2.1 @@ -367,7 +391,7 @@ importers: version: 0.24.2 eslint: specifier: 'catalog:' - version: 9.27.0(jiti@2.4.2) + version: 9.30.1(jiti@2.4.2) memfs: specifier: ^4.17.2 version: 4.17.2 @@ -389,10 +413,10 @@ importers: devDependencies: '@antfu/eslint-config': specifier: 'catalog:' - version: 4.13.1(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@26.0.0)) + version: 4.16.2(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.0.10)(jsdom@26.0.0)) eslint: specifier: 'catalog:' - version: 9.27.0(jiti@2.4.2) + version: 9.30.1(jiti@2.4.2) typescript: specifier: 'catalog:' version: 5.8.3 @@ -401,7 +425,7 @@ importers: version: 3.5.0(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)) vitest: specifier: 'catalog:' - version: 3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@26.0.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.0.10)(jsdom@26.0.0) packages/cli: dependencies: @@ -432,16 +456,16 @@ importers: devDependencies: '@antfu/eslint-config': specifier: 'catalog:' - version: 4.13.1(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@26.0.0)) + version: 4.16.2(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(jsdom@26.0.0)) '@types/mime-types': specifier: ^2.1.4 version: 2.1.4 '@types/node': specifier: 'catalog:' - version: 22.15.21 + version: 22.16.0 eslint: specifier: 'catalog:' - version: 9.27.0(jiti@2.4.2) + version: 9.30.1(jiti@2.4.2) tsx: specifier: ^4.19.3 version: 4.19.4 @@ -453,7 +477,7 @@ importers: version: 3.5.0(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)) vitest: specifier: 'catalog:' - version: 3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@26.0.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(jsdom@26.0.0) packages/lecture: dependencies: @@ -469,16 +493,16 @@ importers: devDependencies: '@antfu/eslint-config': specifier: 'catalog:' - version: 4.13.1(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@26.0.0)) + version: 4.16.2(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(jsdom@26.0.0)) '@types/node': specifier: 'catalog:' - version: 22.15.21 + version: 22.16.0 '@vitest/coverage-v8': specifier: 'catalog:' - version: 3.1.3(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@26.0.0)) + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(jsdom@26.0.0)) eslint: specifier: 'catalog:' - version: 9.27.0(jiti@2.4.2) + version: 9.30.1(jiti@2.4.2) mime: specifier: ^4.0.6 version: 4.0.7 @@ -493,7 +517,7 @@ importers: version: 3.5.0(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)) vitest: specifier: 'catalog:' - version: 3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@26.0.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(jsdom@26.0.0) packages/webhooks: dependencies: @@ -509,10 +533,10 @@ importers: devDependencies: '@antfu/eslint-config': specifier: 'catalog:' - version: 4.13.1(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@26.0.0)) + version: 4.16.2(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.0.10)(jsdom@26.0.0)) eslint: specifier: 'catalog:' - version: 9.27.0(jiti@2.4.2) + version: 9.30.1(jiti@2.4.2) typescript: specifier: 'catalog:' version: 5.8.3 @@ -521,7 +545,7 @@ importers: version: 3.5.0(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)) vitest: specifier: 'catalog:' - version: 3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@26.0.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.0.10)(jsdom@26.0.0) packages: @@ -575,8 +599,8 @@ packages: svelte-eslint-parser: optional: true - '@antfu/eslint-config@4.13.1': - resolution: {integrity: sha512-Ldv0gzQEDH/M+6NfhVBK/9NTDwsYJuHHJBPaFQN9X6LGd927sfEWzMHQdEbrA7f8Rr6abbinReifK7OjDipJ/g==} + '@antfu/eslint-config@4.16.2': + resolution: {integrity: sha512-5KHZR+7ne+HZnOJUKeTTdHKYA/yOygPssaJ7TZOMoBqjSMtVAa7FO5Wvu2dEtkibM6v3emYyKnQnia1S8NHQeA==} hasBin: true peerDependencies: '@eslint-react/eslint-plugin': ^1.38.4 @@ -963,6 +987,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.28.0': + resolution: {integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-syntax-jsx@7.25.9': resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} engines: {node: '>=6.9.0'} @@ -989,6 +1018,10 @@ packages: resolution: {integrity: sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==} engines: {node: '>=6.9.0'} + '@babel/types@7.28.0': + resolution: {integrity: sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==} + engines: {node: '>=6.9.0'} + '@bcoe/v8-coverage@1.0.2': resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} @@ -1069,9 +1102,15 @@ packages: '@clack/core@0.4.2': resolution: {integrity: sha512-NYQfcEy8MWIxrT5Fj8nIVchfRFA26yYKJcvBS7WlUIlw2OmQOY9DhGGXMovyI5J5PpxrCPGkgUi207EBrjpBvg==} + '@clack/core@0.5.0': + resolution: {integrity: sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==} + '@clack/prompts@0.10.1': resolution: {integrity: sha512-Q0T02vx8ZM9XSv9/Yde0jTmmBQufZhPJfYAg2XrrrxWWaZgq1rr8nU8Hv710BQ1dhoP8rtY7YUdpGej2Qza/cw==} + '@clack/prompts@0.11.0': + resolution: {integrity: sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==} + '@clack/prompts@0.9.1': resolution: {integrity: sha512-JIpyaboYZeWYlyP0H+OoPPxd6nqueG/CmN6ixBiNFsIDHREevjIf0n0Ohh5gr5C8pEDknzgvz+pIJ8dMhzWIeg==} @@ -1158,15 +1197,9 @@ packages: '@drizzle-team/brocli@0.10.2': resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==} - '@emnapi/core@1.4.3': - resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==} - '@emnapi/runtime@1.4.3': resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} - '@emnapi/wasi-threads@1.0.2': - resolution: {integrity: sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==} - '@es-joy/jsdoccomment@0.50.0': resolution: {integrity: sha512-+zZymuVLH6zVwXPtCAtC+bDymxmEwEqDftdAK+f407IF1bnX49anIxvBhCA1AqUIfD6egj1jM1vUnSuijjNyYg==} engines: {node: '>=18'} @@ -1175,6 +1208,14 @@ packages: resolution: {integrity: sha512-fas3qe1hw38JJgU/0m5sDpcrbZGysBeZcMwW5Ws9brYxY64MJyWLXRZCj18keTycT1LFTrFXdSNMS+GRVaU6Hw==} engines: {node: '>=18'} + '@es-joy/jsdoccomment@0.50.2': + resolution: {integrity: sha512-YAdE/IJSpwbOTiaURNCKECdAwqrJuFiZhylmesBcIRawtYKnBR2wxPhoIewMg+Yu+QuYvHfJNReWpoxGBKOChA==} + engines: {node: '>=18'} + + '@es-joy/jsdoccomment@0.52.0': + resolution: {integrity: sha512-BXuN7BII+8AyNtn57euU2Yxo9yA/KUDNzrpXyi3pfqKmBhhysR6ZWOebFh3vyPoqA3/j1SOvGgucElMGwlXing==} + engines: {node: '>=20.11.0'} + '@esbuild-kit/core-utils@3.3.2': resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} deprecated: 'Merged into tsx: https://tsx.is' @@ -2085,12 +2126,16 @@ packages: resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/config-array@0.21.0': + resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/config-helpers@0.2.1': resolution: {integrity: sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.10.0': - resolution: {integrity: sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==} + '@eslint/config-helpers@0.3.0': + resolution: {integrity: sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/core@0.13.0': @@ -2101,6 +2146,10 @@ packages: resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@0.15.1': + resolution: {integrity: sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/eslintrc@3.3.1': resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2109,12 +2158,16 @@ packages: resolution: {integrity: sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/js@9.30.1': + resolution: {integrity: sha512-zXhuECFlyep42KZUhWjfvsmXGX39W8K8LFb8AWXM9gSV9dQB+MrJGLKvW6Zw0Ggnbpw0VHTtrhFXYe3Gym18jg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/markdown@6.2.1': resolution: {integrity: sha512-cKVd110hG4ICHmWhIwZJfKmmJBvbiDWyrHODJknAtudKgZtlROGoLX9UEOA0o746zC0hCY4UV4vR+aOGW9S6JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/markdown@6.4.0': - resolution: {integrity: sha512-J07rR8uBSNFJ9iliNINrchilpkmCihPmTVotpThUeKEn5G8aBBZnkjNBy/zovhJA5LBk1vWU9UDlhqKSc/dViQ==} + '@eslint/markdown@6.6.0': + resolution: {integrity: sha512-IsWPy2jU3gaQDlioDC4sT4I4kG1hX1OMWs/q2sWwJrPoMASHW/Z4SDw+6Aql6EsHejGbagYuJbFq9Zvx+Y1b1Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.6': @@ -2129,6 +2182,10 @@ packages: resolution: {integrity: sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/plugin-kit@0.3.3': + resolution: {integrity: sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@expressive-code/core@0.41.2': resolution: {integrity: sha512-AJW5Tp9czbLqKMzwudL9Rv4js9afXBxkSGLmCNPq1iRgAYcx9NkTPJiSNCesjKRWoVC328AdSu6fqrD22zDgDg==} @@ -2325,9 +2382,15 @@ packages: '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/sourcemap-codec@1.5.4': + resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==} + '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.29': + resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} + '@jsonjoy.com/base64@1.1.2': resolution: {integrity: sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==} engines: {node: '>=10.0'} @@ -2497,9 +2560,6 @@ packages: resolution: {integrity: sha512-LQESrePLEBLvhuFkXx9jjBXRC2ClYsO5mqQ1m/puth5z9SOuM3N/B3vDuqnC3RJFktDktyK9khGvo7dTkqO9uQ==} engines: {node: '>= 10'} - '@napi-rs/wasm-runtime@0.2.10': - resolution: {integrity: sha512-bCsCyeZEwVErsGmyPNSzwfwFn4OdxBj0mmv6hOFucB/k81Ojdu68RbZdxYsRQUPc9l6SU5F/cG+bXgWs3oUgsQ==} - '@neon-rs/load@0.0.4': resolution: {integrity: sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==} @@ -2514,6 +2574,10 @@ packages: resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==} engines: {node: ^14.21.3 || >=16} + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -2602,6 +2666,10 @@ packages: resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@pkgr/core@0.2.7': + resolution: {integrity: sha512-YLT9Zo3oNPJoBjBc4q8G2mjU4tqIbf5CEOORbUUr48dCD9q3umJ3IPlVqOqDakPfd2HuwccBaqlGhN4Gmr5OWg==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@playwright/test@1.53.1': resolution: {integrity: sha512-Z4c23LHV0muZ8hfv4jw6HngPJkbbtZxTkxPNIg7cJcTc9C28N/p2q7g3JZS2SiKBBHJ3uM1dgDye66bB7LEk5w==} engines: {node: '>=18'} @@ -3132,8 +3200,8 @@ packages: peerDependencies: eslint: '>=8.40.0' - '@stylistic/eslint-plugin@4.2.0': - resolution: {integrity: sha512-8hXezgz7jexGHdo5WN6JBEIPHCSFyyU4vgbxevu4YLVS5vl+sxqAAGyXSzfNDyR6xMNSH5H1x67nsXcYMOHtZA==} + '@stylistic/eslint-plugin@5.1.0': + resolution: {integrity: sha512-TJRJul4u/lmry5N/kyCU+7RWWOk0wyXN+BncRlDYBqpLFnzXkd7QGVfN7KewarFIXv0IX0jSF/Ksu7aHWEDeuw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: '>=9.0.0' @@ -3166,9 +3234,6 @@ packages: resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} - '@tybys/wasm-util@0.9.0': - resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} - '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -3184,9 +3249,15 @@ packages: '@types/backblaze-b2@1.5.6': resolution: {integrity: sha512-IGx7YhySgHYLns8nkDGPcejPpoG20eHdLBjtJK+QIh44OvG/QOBfCivfRajVoYKf2tczqCY/KIdOin6BfkF18Q==} + '@types/chai@5.2.2': + resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} + '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@types/doctrine@0.0.9': resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==} @@ -3199,6 +3270,9 @@ packages: '@types/estree@1.0.7': resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/fontkit@2.0.8': resolution: {integrity: sha512-wN+8bYxIpJf+5oZdrdtaX04qUuWHcKxcDEgRS9Qm9ZClSHjzEn13SxUC+5eRM+4yXIeTYk8mTzLAWGF64847ew==} @@ -3244,6 +3318,12 @@ packages: '@types/node@22.15.21': resolution: {integrity: sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==} + '@types/node@22.16.0': + resolution: {integrity: sha512-B2egV9wALML1JCpv3VQoQ+yesQKAmNMBIAY7OteVrikcOcAkWm+dGL6qpeCktPjAv6N1JLnhbNiqS35UpFyBsQ==} + + '@types/node@24.0.10': + resolution: {integrity: sha512-ENHwaH+JIRTDIEEbDK6QSQntAYGtbvdDXnMXnZaZ6k13Du1dPMmprkEHIL7ok2Wl2aZevetwTAb5S+7yIF+enA==} + '@types/nodemailer@6.4.17': resolution: {integrity: sha512-I9CCaIp6DTldEg7vyUTZi8+9Vo0hi1/T8gv3C89yk1rSAAzoKQ8H8ki/jBYJSFoH/BisgLP8tkZMlQ91CIquww==} @@ -3285,6 +3365,14 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/eslint-plugin@8.35.1': + resolution: {integrity: sha512-9XNTlo7P7RJxbVeICaIIIEipqxLKguyh+3UbXuT2XQuFp6d8VOeDEGuz5IiX0dgZo8CiI6aOFLg4e8cF71SFVg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.35.1 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/parser@8.32.1': resolution: {integrity: sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3292,6 +3380,19 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/parser@8.35.1': + resolution: {integrity: sha512-3MyiDfrfLeK06bi/g9DqJxP5pV74LNv4rFTyvGDmT3x2p1yp1lOd+qYZfiRPIOf/oON+WRZR5wxxuF85qOar+w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/project-service@8.35.1': + resolution: {integrity: sha512-VYxn/5LOpVxADAuP3NrnxxHYfzVtQzLKeldIhDhzC8UHaiQvYlXvKuVho1qLduFbJjjy5U5bkGwa3rUGUb1Q6Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/scope-manager@8.19.1': resolution: {integrity: sha512-60L9KIuN/xgmsINzonOcMDSB8p82h95hoBfSBtXuO4jlR1R9L1xSkmVZKgCPVfavDlXihh4ARNjXhh1gGnLC7Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3308,6 +3409,16 @@ packages: resolution: {integrity: sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/scope-manager@8.35.1': + resolution: {integrity: sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.35.1': + resolution: {integrity: sha512-K5/U9VmT9dTHoNowWZpz+/TObS3xqC5h0xAIjXPw+MNcKV9qg6eSatEnmeAwkjHijhACH0/N7bkhKvbt1+DXWQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/type-utils@8.32.1': resolution: {integrity: sha512-mv9YpQGA8iIsl5KyUPi+FGLm7+bA4fgXaeRcFKRDRwDMu4iwrSHeDPipwueNXhdIIZltwCJv+NkxftECbIZWfA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3315,6 +3426,13 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/type-utils@8.35.1': + resolution: {integrity: sha512-HOrUBlfVRz5W2LIKpXzZoy6VTZzMu2n8q9C2V/cFngIC5U1nStJgv0tMV4sZPzdf4wQm9/ToWUFPMN9Vq9VJQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/types@8.19.1': resolution: {integrity: sha512-JBVHMLj7B1K1v1051ZaMMgLW4Q/jre5qGK0Ew6UgXz1Rqh+/xPzV1aW581OM00X6iOfyr1be+QyW8LOUf19BbA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3331,6 +3449,10 @@ packages: resolution: {integrity: sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.35.1': + resolution: {integrity: sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@8.19.1': resolution: {integrity: sha512-jk/TZwSMJlxlNnqhy0Eod1PNEvCkpY6MXOXE/WLlblZ6ibb32i2We4uByoKPv1d0OD2xebDv4hbs3fm11SMw8Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3355,6 +3477,12 @@ packages: peerDependencies: typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/typescript-estree@8.35.1': + resolution: {integrity: sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/utils@8.19.1': resolution: {integrity: sha512-IxG5gLO0Ne+KaUc8iW1A+XuKLd63o4wlbI1Zp692n1xojCl/THvgIKXJXBZixTh5dd5+yTJ/VXH7GJaaw21qXA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3376,6 +3504,13 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/utils@8.35.1': + resolution: {integrity: sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/visitor-keys@8.19.1': resolution: {integrity: sha512-fzmjU8CHK853V/avYZAvuVut3ZTfwN5YtMaoi+X9Y9MA9keaWNHC3zEQ9zvyX/7Hj+5JkNyK1l7TOR2hevHB6Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3392,6 +3527,10 @@ packages: resolution: {integrity: sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/visitor-keys@8.35.1': + resolution: {integrity: sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} @@ -3478,91 +3617,6 @@ packages: peerDependencies: vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 - '@unrs/resolver-binding-darwin-arm64@1.7.2': - resolution: {integrity: sha512-vxtBno4xvowwNmO/ASL0Y45TpHqmNkAaDtz4Jqb+clmcVSSl8XCG/PNFFkGsXXXS6AMjP+ja/TtNCFFa1QwLRg==} - cpu: [arm64] - os: [darwin] - - '@unrs/resolver-binding-darwin-x64@1.7.2': - resolution: {integrity: sha512-qhVa8ozu92C23Hsmv0BF4+5Dyyd5STT1FolV4whNgbY6mj3kA0qsrGPe35zNR3wAN7eFict3s4Rc2dDTPBTuFQ==} - cpu: [x64] - os: [darwin] - - '@unrs/resolver-binding-freebsd-x64@1.7.2': - resolution: {integrity: sha512-zKKdm2uMXqLFX6Ac7K5ElnnG5VIXbDlFWzg4WJ8CGUedJryM5A3cTgHuGMw1+P5ziV8CRhnSEgOnurTI4vpHpg==} - cpu: [x64] - os: [freebsd] - - '@unrs/resolver-binding-linux-arm-gnueabihf@1.7.2': - resolution: {integrity: sha512-8N1z1TbPnHH+iDS/42GJ0bMPLiGK+cUqOhNbMKtWJ4oFGzqSJk/zoXFzcQkgtI63qMcUI7wW1tq2usZQSb2jxw==} - cpu: [arm] - os: [linux] - - '@unrs/resolver-binding-linux-arm-musleabihf@1.7.2': - resolution: {integrity: sha512-tjYzI9LcAXR9MYd9rO45m1s0B/6bJNuZ6jeOxo1pq1K6OBuRMMmfyvJYval3s9FPPGmrldYA3mi4gWDlWuTFGA==} - cpu: [arm] - os: [linux] - - '@unrs/resolver-binding-linux-arm64-gnu@1.7.2': - resolution: {integrity: sha512-jon9M7DKRLGZ9VYSkFMflvNqu9hDtOCEnO2QAryFWgT6o6AXU8du56V7YqnaLKr6rAbZBWYsYpikF226v423QA==} - cpu: [arm64] - os: [linux] - - '@unrs/resolver-binding-linux-arm64-musl@1.7.2': - resolution: {integrity: sha512-c8Cg4/h+kQ63pL43wBNaVMmOjXI/X62wQmru51qjfTvI7kmCy5uHTJvK/9LrF0G8Jdx8r34d019P1DVJmhXQpA==} - cpu: [arm64] - os: [linux] - - '@unrs/resolver-binding-linux-ppc64-gnu@1.7.2': - resolution: {integrity: sha512-A+lcwRFyrjeJmv3JJvhz5NbcCkLQL6Mk16kHTNm6/aGNc4FwPHPE4DR9DwuCvCnVHvF5IAd9U4VIs/VvVir5lg==} - cpu: [ppc64] - os: [linux] - - '@unrs/resolver-binding-linux-riscv64-gnu@1.7.2': - resolution: {integrity: sha512-hQQ4TJQrSQW8JlPm7tRpXN8OCNP9ez7PajJNjRD1ZTHQAy685OYqPrKjfaMw/8LiHCt8AZ74rfUVHP9vn0N69Q==} - cpu: [riscv64] - os: [linux] - - '@unrs/resolver-binding-linux-riscv64-musl@1.7.2': - resolution: {integrity: sha512-NoAGbiqrxtY8kVooZ24i70CjLDlUFI7nDj3I9y54U94p+3kPxwd2L692YsdLa+cqQ0VoqMWoehDFp21PKRUoIQ==} - cpu: [riscv64] - os: [linux] - - '@unrs/resolver-binding-linux-s390x-gnu@1.7.2': - resolution: {integrity: sha512-KaZByo8xuQZbUhhreBTW+yUnOIHUsv04P8lKjQ5otiGoSJ17ISGYArc+4vKdLEpGaLbemGzr4ZeUbYQQsLWFjA==} - cpu: [s390x] - os: [linux] - - '@unrs/resolver-binding-linux-x64-gnu@1.7.2': - resolution: {integrity: sha512-dEidzJDubxxhUCBJ/SHSMJD/9q7JkyfBMT77Px1npl4xpg9t0POLvnWywSk66BgZS/b2Hy9Y1yFaoMTFJUe9yg==} - cpu: [x64] - os: [linux] - - '@unrs/resolver-binding-linux-x64-musl@1.7.2': - resolution: {integrity: sha512-RvP+Ux3wDjmnZDT4XWFfNBRVG0fMsc+yVzNFUqOflnDfZ9OYujv6nkh+GOr+watwrW4wdp6ASfG/e7bkDradsw==} - cpu: [x64] - os: [linux] - - '@unrs/resolver-binding-wasm32-wasi@1.7.2': - resolution: {integrity: sha512-y797JBmO9IsvXVRCKDXOxjyAE4+CcZpla2GSoBQ33TVb3ILXuFnMrbR/QQZoauBYeOFuu4w3ifWLw52sdHGz6g==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@unrs/resolver-binding-win32-arm64-msvc@1.7.2': - resolution: {integrity: sha512-gtYTh4/VREVSLA+gHrfbWxaMO/00y+34htY7XpioBTy56YN2eBjkPrY1ML1Zys89X3RJDKVaogzwxlM1qU7egg==} - cpu: [arm64] - os: [win32] - - '@unrs/resolver-binding-win32-ia32-msvc@1.7.2': - resolution: {integrity: sha512-Ywv20XHvHTDRQs12jd3MY8X5C8KLjDbg/jyaal/QLKx3fAShhJyD4blEANInsjxW3P7isHx1Blt56iUDDJO3jg==} - cpu: [ia32] - os: [win32] - - '@unrs/resolver-binding-win32-x64-msvc@1.7.2': - resolution: {integrity: sha512-friS8NEQfHaDbkThxopGk+LuE5v3iY0StruifjQEt7SLbA46OnfgMO15sOTkbpJkol6RB+1l1TYPXh0sCddpvA==} - cpu: [x64] - os: [win32] - '@vitest/coverage-v8@3.1.3': resolution: {integrity: sha512-cj76U5gXCl3g88KSnf80kof6+6w+K4BjOflCl7t6yRJPDuCrHtVu0SgNYOUARJOL5TI8RScDbm5x4s1/P9bvpw==} peerDependencies: @@ -3572,6 +3626,15 @@ packages: '@vitest/browser': optional: true + '@vitest/coverage-v8@3.2.4': + resolution: {integrity: sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==} + peerDependencies: + '@vitest/browser': 3.2.4 + vitest: 3.2.4 + peerDependenciesMeta: + '@vitest/browser': + optional: true + '@vitest/eslint-plugin@1.1.25': resolution: {integrity: sha512-u8DpDnMbPcqBmJOB4PeEtn6q7vKmLVTLFMpzoxSAo0hjYdl4iYSHRleqwPQo0ywc7UV0S6RKIahYRQ3BnZdMVw==} peerDependencies: @@ -3585,8 +3648,8 @@ packages: vitest: optional: true - '@vitest/eslint-plugin@1.2.0': - resolution: {integrity: sha512-6vn3QDy+ysqHGkbH9fU9uyWptqNc638dgPy0uAlh/XpniTBp+0WeVlXGW74zqggex/CwYOhK8t5GVo/FH3NMPw==} + '@vitest/eslint-plugin@1.3.4': + resolution: {integrity: sha512-EOg8d0jn3BAiKnR55WkFxmxfWA3nmzrbIIuOXyTe6A72duryNgyU+bdBEauA97Aab3ho9kLmAwgPX63Ckj4QEg==} peerDependencies: eslint: '>= 8.57.0' typescript: '>= 5.0.0' @@ -3600,6 +3663,9 @@ packages: '@vitest/expect@3.1.3': resolution: {integrity: sha512-7FTQQuuLKmN1Ig/h+h/GO+44Q1IlglPlR2es4ab7Yvfx+Uk5xsv+Ykk+MEt/M2Yn/xGmzaLKxGw2lgy2bwuYqg==} + '@vitest/expect@3.2.4': + resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + '@vitest/mocker@3.1.3': resolution: {integrity: sha512-PJbLjonJK82uCWHjzgBJZuR7zmAOrSvKk1QBxrennDIgtH4uK0TB1PvYmc0XBCigxxtiAVPfWtAdy4lpz8SQGQ==} peerDependencies: @@ -3611,21 +3677,47 @@ packages: vite: optional: true + '@vitest/mocker@3.2.4': + resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + '@vitest/pretty-format@3.1.3': resolution: {integrity: sha512-i6FDiBeJUGLDKADw2Gb01UtUNb12yyXAqC/mmRWuYl+m/U9GS7s8us5ONmGkGpUUo7/iAYzI2ePVfOZTYvUifA==} + '@vitest/pretty-format@3.2.4': + resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + '@vitest/runner@3.1.3': resolution: {integrity: sha512-Tae+ogtlNfFei5DggOsSUvkIaSuVywujMj6HzR97AHK6XK8i3BuVyIifWAm/sE3a15lF5RH9yQIrbXYuo0IFyA==} + '@vitest/runner@3.2.4': + resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} + '@vitest/snapshot@3.1.3': resolution: {integrity: sha512-XVa5OPNTYUsyqG9skuUkFzAeFnEzDp8hQu7kZ0N25B1+6KjGm4hWLtURyBbsIAOekfWQ7Wuz/N/XXzgYO3deWQ==} + '@vitest/snapshot@3.2.4': + resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} + '@vitest/spy@3.1.3': resolution: {integrity: sha512-x6w+ctOEmEXdWaa6TO4ilb7l9DxPR5bwEb6hILKuxfU1NqWT2mpJD9NJN7t3OTfxmVlOMrvtoFJGdgyzZ605lQ==} + '@vitest/spy@3.2.4': + resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} + '@vitest/utils@3.1.3': resolution: {integrity: sha512-2Ltrpht4OmHO9+c/nmHtF09HWiyWdworqnHIwjfvDyWjuwKbdkcS9AnhsDn+8E2RM4x++foD1/tNuLPVvWG1Rg==} + '@vitest/utils@3.2.4': + resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + '@vue/compiler-core@3.5.13': resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} @@ -3668,6 +3760,11 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} @@ -3713,8 +3810,8 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} - ansis@4.0.0: - resolution: {integrity: sha512-P8nrHI1EyW9OfBt1X7hMSwGN2vwRuqHSKJAT1gbLWZRzDa24oHjYwGHvEgHeBepupzk878yS/HBZ0NMPYtbolw==} + ansis@4.1.0: + resolution: {integrity: sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==} engines: {node: '>=14'} anymatch@3.1.3: @@ -3761,6 +3858,9 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + ast-v8-to-istanbul@0.3.3: + resolution: {integrity: sha512-MuXMrSLVVoA6sYN/6Hke18vMzrT4TZNbZIj/hvh0fnYFpO+/kFXcLIaiPwXXWaQUPg4yJD8fj+lfJ7/1EBconw==} + astring@1.9.0: resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} hasBin: true @@ -3873,9 +3973,15 @@ packages: bcp-47@2.1.0: resolution: {integrity: sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==} + better-auth@1.2.12: + resolution: {integrity: sha512-YicCyjQ+lxb7YnnaCewrVOjj3nPVa0xcfrOJK7k5MLMX9Mt9UnJ8GYaVQNHOHLyVxl92qc3C758X1ihqAUzm4w==} + better-auth@1.2.8: resolution: {integrity: sha512-y8ry7ZW3/3ZIr82Eo1zUDtMzdoQlFnwNuZ0+b0RxoNZgqmvgTIc/0tCDC7NDJerqSu4UCzer0dvYxBsv3WMIGg==} + better-call@1.0.11: + resolution: {integrity: sha512-MOM01EMZFMzApWq9+WfqAnl2+DzFoMNp4H+lTFE1p7WF4evMeaQAAcOhI1WwMjITV4PGIWJ3Vn5GciQ5VHXbIA==} + better-call@1.0.9: resolution: {integrity: sha512-Qfm0gjk0XQz0oI7qvTK1hbqTsBY4xV2hsHAxF8LZfUYl3RaECCIifXuVqtPpZJWvlCCMlQSvkvhhyuApGUba6g==} @@ -4242,8 +4348,8 @@ packages: resolution: {integrity: sha512-ZgW+Jgdd7i52AaLYCriF8Mxqft0gD/R9i9wi6RWBhs1pqdPEzPjym7rvRKi397WmQFf3SlyUsszhw+VVCbx79Q==} engines: {node: '>=18'} - cssstyle@4.5.0: - resolution: {integrity: sha512-/7gw8TGrvH/0g564EnhgFZogTMVe+lifpB7LWU+PEsiq5o83TUXR3fDbzTRXOJhoJwck5IS9ez3Em5LNMMO2aw==} + cssstyle@4.6.0: + resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==} engines: {node: '>=18'} csstype@3.1.3: @@ -4546,8 +4652,8 @@ packages: resolution: {integrity: sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==} engines: {node: '>=10.13.0'} - enhanced-resolve@5.18.1: - resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + enhanced-resolve@5.18.2: + resolution: {integrity: sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==} engines: {node: '>=10.13.0'} enquirer@2.4.1: @@ -4660,6 +4766,12 @@ packages: peerDependencies: eslint: '>=6.0.0' + eslint-compat-utils@0.6.5: + resolution: {integrity: sha512-vAUHYzue4YAa2hNACjB8HvUQj5yehAZgiClyFVVom9cP8z5NSFq3PwB/TtJslN2zAMgRX6FCFCjYBbQh71g5RQ==} + engines: {node: '>=12'} + peerDependencies: + eslint: '>=6.0.0' + eslint-config-flat-gitignore@1.0.0: resolution: {integrity: sha512-EWpSLrAP80IdcYK5sIhq/qAY0pmUdBnbzqzpE3QAn6H6wLBN26cMRoMNU9Di8upTzUSL6TXeYRxWhTYuz8+UQA==} peerDependencies: @@ -4673,8 +4785,8 @@ packages: eslint-flat-config-utils@1.1.0: resolution: {integrity: sha512-W49wz7yQJGRfg4QSV3nwdO/fYcWetiSKhLV5YykfQMcqnIATNpoS7EPdINhLB9P3fmdjNmFtOgZjiKnCndWAnw==} - eslint-flat-config-utils@2.0.1: - resolution: {integrity: sha512-brf0eAgQ6JlKj3bKfOTuuI7VcCZvi8ZCD1MMTVoEvS/d38j8cByZViLFALH/36+eqB17ukmfmKq3bWzGvizejA==} + eslint-flat-config-utils@2.1.0: + resolution: {integrity: sha512-6fjOJ9tS0k28ketkUcQ+kKptB4dBZY2VijMZ9rGn8Cwnn1SH0cZBoPXT8AHBFHxmHcLFQK9zbELDinZ2Mr1rng==} eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} @@ -4721,8 +4833,8 @@ packages: peerDependencies: eslint: '*' - eslint-plugin-command@3.2.0: - resolution: {integrity: sha512-PSDOB9k7Wd57pp4HD/l3C1D93pKX8/wQo0kWDI4q6/UpgrfMTyNsavklipgiZqbXl1+VBABY1buCcQE5LDpg5g==} + eslint-plugin-command@3.3.1: + resolution: {integrity: sha512-fBVTXQ2y48TVLT0+4A6PFINp7GcdIailHAXbvPBixE7x+YpYnNQhFZxTdvnb+aWk+COgNebQKen/7m4dmgyWAw==} peerDependencies: eslint: '*' @@ -4732,11 +4844,15 @@ packages: peerDependencies: eslint: '>=8' - eslint-plugin-import-x@4.12.2: - resolution: {integrity: sha512-0jVUgJQipbs0yUfLe7LwYD6p8rIGqCysWZdyJFgkPzDyJgiKpuCaXlywKUAWgJ6u1nLpfrdt21B60OUkupyBrQ==} + eslint-plugin-import-lite@0.3.0: + resolution: {integrity: sha512-dkNBAL6jcoCsXZsQ/Tt2yXmMDoNt5NaBh/U7yvccjiK8cai6Ay+MK77bMykmqQA2bTF6lngaLCDij6MTO3KkvA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 + eslint: '>=9.0.0' + typescript: '>=4.5' + peerDependenciesMeta: + typescript: + optional: true eslint-plugin-import-x@4.6.1: resolution: {integrity: sha512-wluSUifMIb7UfwWXqx7Yx0lE/SGCcGXECLx/9bCmbY2nneLwvAZ4vkd1IXDjPKFvdcdUgr1BaRnaRpx3k2+Pfw==} @@ -4750,14 +4866,20 @@ packages: peerDependencies: eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 + eslint-plugin-jsdoc@51.3.3: + resolution: {integrity: sha512-8XK/9wncTh4PPntQfM4iYJ2v/kvX4qsfBzp+dTnyxpERWhl2R9hEJw1ihws+yAecg9CC6ExTfMInEg3wSK9kWA==} + engines: {node: '>=20.11.0'} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 + eslint-plugin-jsonc@2.18.2: resolution: {integrity: sha512-SDhJiSsWt3nItl/UuIv+ti4g3m4gpGkmnUJS9UWR3TrpyNsIcnJoBRD7Kof6cM4Rk3L0wrmY5Tm3z7ZPjR2uGg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '>=6.0.0' - eslint-plugin-jsonc@2.20.0: - resolution: {integrity: sha512-FRgCn9Hzk5eKboCbVMrr9QrhM0eO4G+WKH8IFXoaeqhM/2kuWzbStJn4kkr0VWL8J5H8RYZF+Aoam1vlBaZVkw==} + eslint-plugin-jsonc@2.20.1: + resolution: {integrity: sha512-gUzIwQHXx7ZPypUoadcyRi4WbHW2TPixDr0kqQ4miuJBU0emJmyGTlnaT3Og9X2a8R1CDayN9BFSq5weGWbTng==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '>=6.0.0' @@ -4768,8 +4890,8 @@ packages: peerDependencies: eslint: '>=8.23.0' - eslint-plugin-n@17.18.0: - resolution: {integrity: sha512-hvZ/HusueqTJ7VDLoCpjN0hx4N4+jHIWTXD4TMLHy9F23XkDagR9v+xQWRWR57yY55GPF8NnD4ox9iGTxirY8A==} + eslint-plugin-n@17.21.0: + resolution: {integrity: sha512-1+iZ8We4ZlwVMtb/DcHG3y5/bZOdazIpa/4TySo22MLKdwrLcfrX0hbadnCvykSQCCmkAnWmIP8jZVb2AAq29A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: '>=8.23.0' @@ -4784,6 +4906,12 @@ packages: peerDependencies: eslint: '>=8.45.0' + eslint-plugin-perfectionist@4.15.0: + resolution: {integrity: sha512-pC7PgoXyDnEXe14xvRUhBII8A3zRgggKqJFx2a82fjrItDs1BSI7zdZnQtM2yQvcyod6/ujmzb7ejKPx8lZTnw==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + eslint: '>=8.45.0' + eslint-plugin-pnpm@0.3.1: resolution: {integrity: sha512-vi5iHoELIAlBbX4AW8ZGzU3tUnfxuXhC/NKo3qRcI5o9igbz6zJUqSlQ03bPeMqWIGTPatZnbWsNR1RnlNERNQ==} peerDependencies: @@ -4795,6 +4923,12 @@ packages: peerDependencies: eslint: '>=8.44.0' + eslint-plugin-regexp@2.9.0: + resolution: {integrity: sha512-9WqJMnOq8VlE/cK+YAo9C9YHhkOtcEtEk9d12a+H7OSZFwlpI6stiHmYPGa2VE0QhTzodJyhlyprUaXDZLgHBw==} + engines: {node: ^18 || >=20} + peerDependencies: + eslint: '>=8.44.0' + eslint-plugin-toml@0.12.0: resolution: {integrity: sha512-+/wVObA9DVhwZB1nG83D2OAQRrcQZXy+drqUnFJKymqnmbnbfg/UPmEMCKrJNcEboUGxUjYrJlgy+/Y930mURQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -4822,12 +4956,16 @@ packages: '@typescript-eslint/eslint-plugin': optional: true - eslint-plugin-vue@10.1.0: - resolution: {integrity: sha512-/VTiJ1eSfNLw6lvG9ENySbGmcVvz6wZ9nA7ZqXlLBY2RkaF15iViYKxglWiIch12KiLAj0j1iXPYU6W4wTROFA==} + eslint-plugin-vue@10.3.0: + resolution: {integrity: sha512-A0u9snqjCfYaPnqqOaH6MBLVWDUIN4trXn8J3x67uDcXvR7X6Ut8p16N+nYhMCQ9Y7edg2BIRGzfyZsY0IdqoQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: + '@typescript-eslint/parser': ^7.0.0 || ^8.0.0 eslint: ^8.57.0 || ^9.0.0 vue-eslint-parser: ^10.0.0 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true eslint-plugin-vue@9.32.0: resolution: {integrity: sha512-b/Y05HYmnB/32wqVcjxjHZzNpwxj1onBOvqW89W+V+XNG1dRuaFbNd3vT9CLbr2LXjEoq+3vn8DanWf7XU22Ug==} @@ -4867,6 +5005,10 @@ packages: resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -4875,6 +5017,10 @@ packages: resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint@9.27.0: resolution: {integrity: sha512-ixRawFQuMB9DZ7fjU3iGGganFDp3+45bPOdaRurcFHSXO1e/sYwUX/FtQZpLZJR6SjMoJH8hR2pPEAfDyCoU2Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4885,10 +5031,24 @@ packages: jiti: optional: true + eslint@9.30.1: + resolution: {integrity: sha512-zmxXPNMOXmwm9E0yQLi5uqXHs7uq2UIiqEKo3Gq+3fwo1XrJ+hijAZImyF7hclW3E6oHz43Yk3RP8at6OTKflQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + espree@10.3.0: resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -5165,6 +5325,9 @@ packages: get-tsconfig@4.10.0: resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} + get-tsconfig@4.10.1: + resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} + giget@2.0.0: resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} hasBin: true @@ -5211,8 +5374,8 @@ packages: resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} engines: {node: '>=18'} - globals@16.1.0: - resolution: {integrity: sha512-aibexHNbb/jiUSObBgpHLj+sIuUmJnYcgXBlrfsiDZ9rt4aF2TFRbyLgZ2iFQuVZ1K5Mx3FVkbKRSgKrbK3K2g==} + globals@16.3.0: + resolution: {integrity: sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==} engines: {node: '>=18'} globby@11.1.0: @@ -5399,6 +5562,10 @@ packages: resolution: {integrity: sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==} engines: {node: '>= 4'} + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} @@ -5582,12 +5749,18 @@ packages: jose@5.10.0: resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} + jose@6.0.11: + resolution: {integrity: sha512-QxG7EaliDARm1O1S8BGakqncGT9s25bKL1WSf6/oa17Tkqwi8D2ZNglqCF+DsYF88/rV66Q/Q2mFAy697E1DUg==} + js-base64@3.7.7: resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true @@ -5754,6 +5927,9 @@ packages: loupe@3.1.3: resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} + loupe@3.1.4: + resolution: {integrity: sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==} + lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -6035,10 +6211,6 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} - minimatch@10.0.1: - resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} - engines: {node: 20 || >=22} - minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -6136,11 +6308,6 @@ packages: napi-build-utils@2.0.0: resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} - napi-postinstall@0.2.4: - resolution: {integrity: sha512-ZEzHJwBhZ8qQSbknHqYcdtQVr8zUgGyM/q6h6qAyhtyVMNrSgDhrC4disf03dYW0e+czXyLnZINnCTEkWy0eJg==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - hasBin: true - natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -7145,9 +7312,6 @@ packages: stable-hash@0.0.4: resolution: {integrity: sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==} - stable-hash@0.0.5: - resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} - stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} @@ -7221,6 +7385,9 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + strip-literal@3.0.0: + resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} + stripe@17.7.0: resolution: {integrity: sha512-aT2BU9KkizY9SATf14WhhYVv2uOapBWX0OFWF4xvcj1mPaNotlSc2CsxpS4DS46ZueSppmCF5BX1sNYBtwBvfw==} engines: {node: '>=12.*'} @@ -7262,6 +7429,10 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + synckit@0.11.8: + resolution: {integrity: sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A==} + engines: {node: ^14.18.0 || >=16.0.0} + synckit@0.6.2: resolution: {integrity: sha512-Vhf+bUa//YSTYKseDiiEuQmhGCoIF3CVBhunm3r/DQnYiGT4JssmnKQc44BIyOZRK2pKjXXAgbhfmbeoC9CJpA==} engines: {node: '>=12.20'} @@ -7277,6 +7448,10 @@ packages: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} + tapable@2.2.2: + resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==} + engines: {node: '>=6'} + tar-fs@2.1.2: resolution: {integrity: sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==} @@ -7341,6 +7516,10 @@ packages: resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} engines: {node: ^18.0.0 || >=20.0.0} + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} + engines: {node: ^18.0.0 || >=20.0.0} + tinyrainbow@2.0.0: resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} engines: {node: '>=14.0.0'} @@ -7349,6 +7528,10 @@ packages: resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} engines: {node: '>=14.0.0'} + tinyspy@4.0.3: + resolution: {integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==} + engines: {node: '>=14.0.0'} + tldts-core@6.1.84: resolution: {integrity: sha512-NaQa1W76W2aCGjXybvnMYzGSM4x8fvG2AN/pla7qxcg0ZHbooOPhA8kctmOZUDfZyhDL27OGNbwAeig8P4p1vg==} @@ -7401,6 +7584,11 @@ packages: peerDependencies: typescript: '>=4.8.4' + ts-declaration-location@1.0.7: + resolution: {integrity: sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==} + peerDependencies: + typescript: '>=4.0.0' + ts-pattern@5.7.1: resolution: {integrity: sha512-EGs8PguQqAAUIcQfK4E9xdXxB6s2GK4sJfT/vcc9V1ELIvC4LH/zXu2t/5fajtv6oiRCxdv7BgtVK3vWgROxag==} @@ -7489,6 +7677,9 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici-types@7.8.0: + resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} + unicode-properties@1.4.1: resolution: {integrity: sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==} @@ -7559,9 +7750,6 @@ packages: unpdf@0.12.1: resolution: {integrity: sha512-ktP8+TTLDBrlu/j8rQVNbHoMMpFXzkVAkb1rt/JdshFC3jOHdZjuGCNl/voPL0kraUrUOH7ZC88kVxMvlvDBzA==} - unrs-resolver@1.7.2: - resolution: {integrity: sha512-BBKpaylOW8KbHsu378Zky/dGh4ckT/4NW/0SHRABdqRLcQJ2dAOjDo9g97p04sWflm0kqPqpUatxReNV/dqI5A==} - unstorage@1.16.0: resolution: {integrity: sha512-WQ37/H5A7LcRPWfYOrDa1Ys02xAbpPJq6q5GkO88FBXVSQzHd7+BjEwfRqyaSWCv9MbsJy058GWjjPjcJ16GGA==} peerDependencies: @@ -7684,6 +7872,11 @@ packages: engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true + vite-node@3.2.4: + resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + vite-plugin-solid@2.11.6: resolution: {integrity: sha512-Sl5CTqJTGyEeOsmdH6BOgalIZlwH3t4/y0RQuFLMGnvWMBvxb4+lq7x3BSiAw6etf0QexfNJW7HSOO/Qf7pigg==} peerDependencies: @@ -7851,8 +8044,36 @@ packages: jsdom: optional: true - vue-eslint-parser@10.1.3: - resolution: {integrity: sha512-dbCBnd2e02dYWsXoqX5yKUZlOt+ExIpq7hmHKPb5ZqKcjf++Eo0hMseFTZMLKThrUk61m+Uv6A2YSBve6ZvuDQ==} + vitest@3.2.4: + resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/debug': ^4.1.12 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + '@vitest/browser': 3.2.4 + '@vitest/ui': 3.2.4 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/debug': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + vue-eslint-parser@10.2.0: + resolution: {integrity: sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -7987,6 +8208,18 @@ packages: utf-8-validate: optional: true + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + xml-name-validator@4.0.0: resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} engines: {node: '>=12'} @@ -8065,6 +8298,9 @@ packages: zod@3.25.67: resolution: {integrity: sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==} + zod@3.25.73: + resolution: {integrity: sha512-fuIKbQAWQl22Ba5d1quwEETQYjqnpKVyZIWAhbnnHgnDd3a+z4YgEfkI5SZ2xMELnLAXo/Flk2uXgysZNf0uaA==} + zustand@5.0.3: resolution: {integrity: sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==} engines: {node: '>=12.20.0'} @@ -8093,7 +8329,7 @@ snapshots: '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 - '@antfu/eslint-config@3.16.0(@typescript-eslint/utils@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jiti@2.4.2)(jsdom@26.0.0)(tsx@4.20.3)(yaml@2.8.0))': + '@antfu/eslint-config@3.16.0(@typescript-eslint/utils@8.35.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.0.10)(jsdom@26.0.0))': dependencies: '@antfu/install-pkg': 1.0.0 '@clack/prompts': 0.9.1 @@ -8102,7 +8338,7 @@ snapshots: '@stylistic/eslint-plugin': 2.13.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) '@typescript-eslint/eslint-plugin': 8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) '@typescript-eslint/parser': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - '@vitest/eslint-plugin': 1.1.25(@typescript-eslint/utils@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jiti@2.4.2)(jsdom@26.0.0)(tsx@4.20.3)(yaml@2.8.0)) + '@vitest/eslint-plugin': 1.1.25(@typescript-eslint/utils@8.35.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.0.10)(jsdom@26.0.0)) eslint: 9.27.0(jiti@2.4.2) eslint-config-flat-gitignore: 1.0.0(eslint@9.27.0(jiti@2.4.2)) eslint-flat-config-utils: 1.1.0 @@ -8142,48 +8378,48 @@ snapshots: - typescript - vitest - '@antfu/eslint-config@4.13.1(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@25.0.1(canvas@2.11.2)))': + '@antfu/eslint-config@4.16.2(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@26.0.0))': dependencies: '@antfu/install-pkg': 1.1.0 - '@clack/prompts': 0.10.1 - '@eslint-community/eslint-plugin-eslint-comments': 4.5.0(eslint@9.27.0(jiti@2.4.2)) - '@eslint/markdown': 6.4.0 - '@stylistic/eslint-plugin': 4.2.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/eslint-plugin': 8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/parser': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - '@vitest/eslint-plugin': 1.2.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@25.0.1(canvas@2.11.2))) - ansis: 4.0.0 + '@clack/prompts': 0.11.0 + '@eslint-community/eslint-plugin-eslint-comments': 4.5.0(eslint@9.30.1(jiti@2.4.2)) + '@eslint/markdown': 6.6.0 + '@stylistic/eslint-plugin': 5.1.0(eslint@9.30.1(jiti@2.4.2)) + '@typescript-eslint/eslint-plugin': 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/parser': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@vitest/eslint-plugin': 1.3.4(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@26.0.0)) + ansis: 4.1.0 cac: 6.7.14 - eslint: 9.27.0(jiti@2.4.2) - eslint-config-flat-gitignore: 2.1.0(eslint@9.27.0(jiti@2.4.2)) - eslint-flat-config-utils: 2.0.1 - eslint-merge-processors: 2.0.0(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-antfu: 3.1.1(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-command: 3.2.0(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-import-x: 4.12.2(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - eslint-plugin-jsdoc: 50.6.17(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-jsonc: 2.20.0(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-n: 17.18.0(eslint@9.27.0(jiti@2.4.2)) + eslint: 9.30.1(jiti@2.4.2) + eslint-config-flat-gitignore: 2.1.0(eslint@9.30.1(jiti@2.4.2)) + eslint-flat-config-utils: 2.1.0 + eslint-merge-processors: 2.0.0(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-antfu: 3.1.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-command: 3.3.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-import-lite: 0.3.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint-plugin-jsdoc: 51.3.3(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-jsonc: 2.20.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-n: 17.21.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) eslint-plugin-no-only-tests: 3.3.0 - eslint-plugin-perfectionist: 4.13.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - eslint-plugin-pnpm: 0.3.1(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-regexp: 2.7.0(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-toml: 0.12.0(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-unicorn: 59.0.1(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-unused-imports: 4.1.4(@typescript-eslint/eslint-plugin@8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-vue: 10.1.0(eslint@9.27.0(jiti@2.4.2))(vue-eslint-parser@10.1.3(eslint@9.27.0(jiti@2.4.2))) - eslint-plugin-yml: 1.18.0(eslint@9.27.0(jiti@2.4.2)) - eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.13)(eslint@9.27.0(jiti@2.4.2)) - globals: 16.1.0 + eslint-plugin-perfectionist: 4.15.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint-plugin-pnpm: 0.3.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-regexp: 2.9.0(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-toml: 0.12.0(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-unicorn: 59.0.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-unused-imports: 4.1.4(@typescript-eslint/eslint-plugin@8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-vue: 10.3.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(vue-eslint-parser@10.2.0(eslint@9.30.1(jiti@2.4.2))) + eslint-plugin-yml: 1.18.0(eslint@9.30.1(jiti@2.4.2)) + eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.13)(eslint@9.30.1(jiti@2.4.2)) + globals: 16.3.0 jsonc-eslint-parser: 2.4.0 local-pkg: 1.1.1 parse-gitignore: 2.0.0 toml-eslint-parser: 0.10.0 - vue-eslint-parser: 10.1.3(eslint@9.27.0(jiti@2.4.2)) + vue-eslint-parser: 10.2.0(eslint@9.30.1(jiti@2.4.2)) yaml-eslint-parser: 1.3.0 optionalDependencies: astro-eslint-parser: 1.1.0(typescript@5.8.3) - eslint-plugin-astro: 1.3.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) + eslint-plugin-astro: 1.3.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) transitivePeerDependencies: - '@eslint/json' - '@vue/compiler-sfc' @@ -8191,48 +8427,146 @@ snapshots: - typescript - vitest - '@antfu/eslint-config@4.13.1(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@26.0.0))': + '@antfu/eslint-config@4.16.2(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(jsdom@25.0.1(canvas@2.11.2)))': dependencies: '@antfu/install-pkg': 1.1.0 - '@clack/prompts': 0.10.1 - '@eslint-community/eslint-plugin-eslint-comments': 4.5.0(eslint@9.27.0(jiti@2.4.2)) - '@eslint/markdown': 6.4.0 - '@stylistic/eslint-plugin': 4.2.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/eslint-plugin': 8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/parser': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - '@vitest/eslint-plugin': 1.2.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@26.0.0)) - ansis: 4.0.0 + '@clack/prompts': 0.11.0 + '@eslint-community/eslint-plugin-eslint-comments': 4.5.0(eslint@9.30.1(jiti@2.4.2)) + '@eslint/markdown': 6.6.0 + '@stylistic/eslint-plugin': 5.1.0(eslint@9.30.1(jiti@2.4.2)) + '@typescript-eslint/eslint-plugin': 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/parser': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@vitest/eslint-plugin': 1.3.4(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(jsdom@25.0.1(canvas@2.11.2))) + ansis: 4.1.0 cac: 6.7.14 - eslint: 9.27.0(jiti@2.4.2) - eslint-config-flat-gitignore: 2.1.0(eslint@9.27.0(jiti@2.4.2)) - eslint-flat-config-utils: 2.0.1 - eslint-merge-processors: 2.0.0(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-antfu: 3.1.1(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-command: 3.2.0(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-import-x: 4.12.2(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - eslint-plugin-jsdoc: 50.6.17(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-jsonc: 2.20.0(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-n: 17.18.0(eslint@9.27.0(jiti@2.4.2)) + eslint: 9.30.1(jiti@2.4.2) + eslint-config-flat-gitignore: 2.1.0(eslint@9.30.1(jiti@2.4.2)) + eslint-flat-config-utils: 2.1.0 + eslint-merge-processors: 2.0.0(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-antfu: 3.1.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-command: 3.3.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-import-lite: 0.3.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint-plugin-jsdoc: 51.3.3(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-jsonc: 2.20.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-n: 17.21.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) eslint-plugin-no-only-tests: 3.3.0 - eslint-plugin-perfectionist: 4.13.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - eslint-plugin-pnpm: 0.3.1(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-regexp: 2.7.0(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-toml: 0.12.0(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-unicorn: 59.0.1(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-unused-imports: 4.1.4(@typescript-eslint/eslint-plugin@8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-vue: 10.1.0(eslint@9.27.0(jiti@2.4.2))(vue-eslint-parser@10.1.3(eslint@9.27.0(jiti@2.4.2))) - eslint-plugin-yml: 1.18.0(eslint@9.27.0(jiti@2.4.2)) - eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.13)(eslint@9.27.0(jiti@2.4.2)) - globals: 16.1.0 + eslint-plugin-perfectionist: 4.15.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint-plugin-pnpm: 0.3.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-regexp: 2.9.0(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-toml: 0.12.0(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-unicorn: 59.0.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-unused-imports: 4.1.4(@typescript-eslint/eslint-plugin@8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-vue: 10.3.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(vue-eslint-parser@10.2.0(eslint@9.30.1(jiti@2.4.2))) + eslint-plugin-yml: 1.18.0(eslint@9.30.1(jiti@2.4.2)) + eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.13)(eslint@9.30.1(jiti@2.4.2)) + globals: 16.3.0 jsonc-eslint-parser: 2.4.0 local-pkg: 1.1.1 parse-gitignore: 2.0.0 toml-eslint-parser: 0.10.0 - vue-eslint-parser: 10.1.3(eslint@9.27.0(jiti@2.4.2)) + vue-eslint-parser: 10.2.0(eslint@9.30.1(jiti@2.4.2)) yaml-eslint-parser: 1.3.0 optionalDependencies: astro-eslint-parser: 1.1.0(typescript@5.8.3) - eslint-plugin-astro: 1.3.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) + eslint-plugin-astro: 1.3.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + transitivePeerDependencies: + - '@eslint/json' + - '@vue/compiler-sfc' + - supports-color + - typescript + - vitest + + '@antfu/eslint-config@4.16.2(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(jsdom@26.0.0))': + dependencies: + '@antfu/install-pkg': 1.1.0 + '@clack/prompts': 0.11.0 + '@eslint-community/eslint-plugin-eslint-comments': 4.5.0(eslint@9.30.1(jiti@2.4.2)) + '@eslint/markdown': 6.6.0 + '@stylistic/eslint-plugin': 5.1.0(eslint@9.30.1(jiti@2.4.2)) + '@typescript-eslint/eslint-plugin': 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/parser': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@vitest/eslint-plugin': 1.3.4(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(jsdom@26.0.0)) + ansis: 4.1.0 + cac: 6.7.14 + eslint: 9.30.1(jiti@2.4.2) + eslint-config-flat-gitignore: 2.1.0(eslint@9.30.1(jiti@2.4.2)) + eslint-flat-config-utils: 2.1.0 + eslint-merge-processors: 2.0.0(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-antfu: 3.1.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-command: 3.3.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-import-lite: 0.3.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint-plugin-jsdoc: 51.3.3(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-jsonc: 2.20.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-n: 17.21.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint-plugin-no-only-tests: 3.3.0 + eslint-plugin-perfectionist: 4.15.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint-plugin-pnpm: 0.3.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-regexp: 2.9.0(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-toml: 0.12.0(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-unicorn: 59.0.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-unused-imports: 4.1.4(@typescript-eslint/eslint-plugin@8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-vue: 10.3.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(vue-eslint-parser@10.2.0(eslint@9.30.1(jiti@2.4.2))) + eslint-plugin-yml: 1.18.0(eslint@9.30.1(jiti@2.4.2)) + eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.13)(eslint@9.30.1(jiti@2.4.2)) + globals: 16.3.0 + jsonc-eslint-parser: 2.4.0 + local-pkg: 1.1.1 + parse-gitignore: 2.0.0 + toml-eslint-parser: 0.10.0 + vue-eslint-parser: 10.2.0(eslint@9.30.1(jiti@2.4.2)) + yaml-eslint-parser: 1.3.0 + optionalDependencies: + astro-eslint-parser: 1.1.0(typescript@5.8.3) + eslint-plugin-astro: 1.3.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + transitivePeerDependencies: + - '@eslint/json' + - '@vue/compiler-sfc' + - supports-color + - typescript + - vitest + + '@antfu/eslint-config@4.16.2(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.8.3))(eslint-plugin-astro@1.3.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.0.10)(jsdom@26.0.0))': + dependencies: + '@antfu/install-pkg': 1.1.0 + '@clack/prompts': 0.11.0 + '@eslint-community/eslint-plugin-eslint-comments': 4.5.0(eslint@9.30.1(jiti@2.4.2)) + '@eslint/markdown': 6.6.0 + '@stylistic/eslint-plugin': 5.1.0(eslint@9.30.1(jiti@2.4.2)) + '@typescript-eslint/eslint-plugin': 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/parser': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@vitest/eslint-plugin': 1.3.4(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.0.10)(jsdom@26.0.0)) + ansis: 4.1.0 + cac: 6.7.14 + eslint: 9.30.1(jiti@2.4.2) + eslint-config-flat-gitignore: 2.1.0(eslint@9.30.1(jiti@2.4.2)) + eslint-flat-config-utils: 2.1.0 + eslint-merge-processors: 2.0.0(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-antfu: 3.1.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-command: 3.3.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-import-lite: 0.3.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint-plugin-jsdoc: 51.3.3(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-jsonc: 2.20.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-n: 17.21.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint-plugin-no-only-tests: 3.3.0 + eslint-plugin-perfectionist: 4.15.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint-plugin-pnpm: 0.3.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-regexp: 2.9.0(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-toml: 0.12.0(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-unicorn: 59.0.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-unused-imports: 4.1.4(@typescript-eslint/eslint-plugin@8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-vue: 10.3.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(vue-eslint-parser@10.2.0(eslint@9.30.1(jiti@2.4.2))) + eslint-plugin-yml: 1.18.0(eslint@9.30.1(jiti@2.4.2)) + eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.13)(eslint@9.30.1(jiti@2.4.2)) + globals: 16.3.0 + jsonc-eslint-parser: 2.4.0 + local-pkg: 1.1.1 + parse-gitignore: 2.0.0 + toml-eslint-parser: 0.10.0 + vue-eslint-parser: 10.2.0(eslint@9.30.1(jiti@2.4.2)) + yaml-eslint-parser: 1.3.0 + optionalDependencies: + astro-eslint-parser: 1.1.0(typescript@5.8.3) + eslint-plugin-astro: 1.3.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) transitivePeerDependencies: - '@eslint/json' - '@vue/compiler-sfc' @@ -8327,12 +8661,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/mdx@4.2.3(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@22.15.21)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))': + '@astrojs/mdx@4.2.3(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@24.0.10)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))': dependencies: '@astrojs/markdown-remark': 6.3.1 '@mdx-js/mdx': 3.1.0(acorn@8.14.1) acorn: 8.14.1 - astro: 5.8.0(@azure/storage-blob@12.27.0)(@types/node@22.15.21)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) + astro: 5.8.0(@azure/storage-blob@12.27.0)(@types/node@24.0.10)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) es-module-lexer: 1.6.0 estree-util-visit: 2.0.0 hast-util-to-html: 9.0.5 @@ -8360,11 +8694,11 @@ snapshots: stream-replace-string: 2.0.0 zod: 3.25.67 - '@astrojs/solid-js@5.1.0(@types/node@22.15.21)(jiti@2.4.2)(solid-js@1.9.7)(tsx@4.20.3)(yaml@2.8.0)': + '@astrojs/solid-js@5.1.0(@types/node@24.0.10)(jiti@2.4.2)(solid-js@1.9.7)(tsx@4.20.3)(yaml@2.8.0)': dependencies: solid-js: 1.9.7 - vite: 6.3.5(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0) - vite-plugin-solid: 2.11.6(solid-js@1.9.7)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0)) + vite: 6.3.5(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0) + vite-plugin-solid: 2.11.6(solid-js@1.9.7)(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0)) transitivePeerDependencies: - '@testing-library/jest-dom' - '@types/node' @@ -8380,17 +8714,17 @@ snapshots: - tsx - yaml - '@astrojs/starlight@0.34.3(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@22.15.21)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))': + '@astrojs/starlight@0.34.3(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@24.0.10)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))': dependencies: '@astrojs/markdown-remark': 6.3.1 - '@astrojs/mdx': 4.2.3(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@22.15.21)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0)) + '@astrojs/mdx': 4.2.3(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@24.0.10)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0)) '@astrojs/sitemap': 3.3.0 '@pagefind/default-ui': 1.3.0 '@types/hast': 3.0.4 '@types/js-yaml': 4.0.9 '@types/mdast': 4.0.4 - astro: 5.8.0(@azure/storage-blob@12.27.0)(@types/node@22.15.21)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) - astro-expressive-code: 0.41.2(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@22.15.21)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0)) + astro: 5.8.0(@azure/storage-blob@12.27.0)(@types/node@24.0.10)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) + astro-expressive-code: 0.41.2(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@24.0.10)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0)) bcp-47: 2.1.0 hast-util-from-html: 2.0.3 hast-util-select: 6.0.4 @@ -9078,6 +9412,10 @@ snapshots: dependencies: '@babel/types': 7.27.6 + '@babel/parser@7.28.0': + dependencies: + '@babel/types': 7.28.0 + '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -9115,6 +9453,11 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@babel/types@7.28.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@bcoe/v8-coverage@1.0.2': {} '@better-auth/utils@0.2.5': @@ -9299,12 +9642,23 @@ snapshots: picocolors: 1.1.1 sisteransi: 1.0.5 + '@clack/core@0.5.0': + dependencies: + picocolors: 1.1.1 + sisteransi: 1.0.5 + '@clack/prompts@0.10.1': dependencies: '@clack/core': 0.4.2 picocolors: 1.1.1 sisteransi: 1.0.5 + '@clack/prompts@0.11.0': + dependencies: + '@clack/core': 0.5.0 + picocolors: 1.1.1 + sisteransi: 1.0.5 + '@clack/prompts@0.9.1': dependencies: '@clack/core': 0.4.1 @@ -9374,22 +9728,11 @@ snapshots: '@drizzle-team/brocli@0.10.2': {} - '@emnapi/core@1.4.3': - dependencies: - '@emnapi/wasi-threads': 1.0.2 - tslib: 2.8.1 - optional: true - '@emnapi/runtime@1.4.3': dependencies: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.0.2': - dependencies: - tslib: 2.8.1 - optional: true - '@es-joy/jsdoccomment@0.50.0': dependencies: '@types/eslint': 9.6.1 @@ -9408,6 +9751,22 @@ snapshots: esquery: 1.6.0 jsdoc-type-pratt-parser: 4.1.0 + '@es-joy/jsdoccomment@0.50.2': + dependencies: + '@types/estree': 1.0.8 + '@typescript-eslint/types': 8.35.1 + comment-parser: 1.4.1 + esquery: 1.6.0 + jsdoc-type-pratt-parser: 4.1.0 + + '@es-joy/jsdoccomment@0.52.0': + dependencies: + '@types/estree': 1.0.8 + '@typescript-eslint/types': 8.35.1 + comment-parser: 1.4.1 + esquery: 1.6.0 + jsdoc-type-pratt-parser: 4.1.0 + '@esbuild-kit/core-utils@3.3.2': dependencies: esbuild: 0.18.20 @@ -9850,10 +10209,10 @@ snapshots: eslint: 9.27.0(jiti@2.4.2) ignore: 5.3.2 - '@eslint-community/eslint-plugin-eslint-comments@4.5.0(eslint@9.27.0(jiti@2.4.2))': + '@eslint-community/eslint-plugin-eslint-comments@4.5.0(eslint@9.30.1(jiti@2.4.2))': dependencies: escape-string-regexp: 4.0.0 - eslint: 9.27.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) ignore: 5.3.2 '@eslint-community/eslint-utils@4.5.1(eslint@9.27.0(jiti@2.4.2))': @@ -9861,20 +10220,31 @@ snapshots: eslint: 9.27.0(jiti@2.4.2) eslint-visitor-keys: 3.4.3 + '@eslint-community/eslint-utils@4.5.1(eslint@9.30.1(jiti@2.4.2))': + dependencies: + eslint: 9.30.1(jiti@2.4.2) + eslint-visitor-keys: 3.4.3 + optional: true + '@eslint-community/eslint-utils@4.7.0(eslint@9.27.0(jiti@2.4.2))': dependencies: eslint: 9.27.0(jiti@2.4.2) eslint-visitor-keys: 3.4.3 + '@eslint-community/eslint-utils@4.7.0(eslint@9.30.1(jiti@2.4.2))': + dependencies: + eslint: 9.30.1(jiti@2.4.2) + eslint-visitor-keys: 3.4.3 + '@eslint-community/regexpp@4.12.1': {} '@eslint/compat@1.2.4(eslint@9.27.0(jiti@2.4.2))': optionalDependencies: eslint: 9.27.0(jiti@2.4.2) - '@eslint/compat@1.2.8(eslint@9.27.0(jiti@2.4.2))': + '@eslint/compat@1.2.8(eslint@9.30.1(jiti@2.4.2))': optionalDependencies: - eslint: 9.27.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) '@eslint/config-array@0.20.0': dependencies: @@ -9884,11 +10254,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@eslint/config-array@0.21.0': + dependencies: + '@eslint/object-schema': 2.1.6 + debug: 4.4.1 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + '@eslint/config-helpers@0.2.1': {} - '@eslint/core@0.10.0': - dependencies: - '@types/json-schema': 7.0.15 + '@eslint/config-helpers@0.3.0': {} '@eslint/core@0.13.0': dependencies: @@ -9898,11 +10274,15 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 + '@eslint/core@0.15.1': + dependencies: + '@types/json-schema': 7.0.15 + '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 debug: 4.4.1 - espree: 10.3.0 + espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.1 @@ -9914,6 +10294,8 @@ snapshots: '@eslint/js@9.27.0': {} + '@eslint/js@9.30.1': {} + '@eslint/markdown@6.2.1': dependencies: '@eslint/plugin-kit': 0.2.8 @@ -9923,10 +10305,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/markdown@6.4.0': + '@eslint/markdown@6.6.0': dependencies: - '@eslint/core': 0.10.0 - '@eslint/plugin-kit': 0.2.8 + '@eslint/core': 0.14.0 + '@eslint/plugin-kit': 0.3.3 + github-slugger: 2.0.0 mdast-util-from-markdown: 2.0.2 mdast-util-frontmatter: 2.0.1 mdast-util-gfm: 3.1.0 @@ -9947,6 +10330,11 @@ snapshots: '@eslint/core': 0.14.0 levn: 0.4.1 + '@eslint/plugin-kit@0.3.3': + dependencies: + '@eslint/core': 0.15.1 + levn: 0.4.1 + '@expressive-code/core@0.41.2': dependencies: '@ctrl/tinycolor': 4.1.0 @@ -10131,11 +10519,18 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/sourcemap-codec@1.5.4': {} + '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping@0.3.29': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.4 + '@jsonjoy.com/base64@1.1.2(tslib@2.8.1)': dependencies: tslib: 2.8.1 @@ -10355,13 +10750,6 @@ snapshots: '@napi-rs/canvas-win32-x64-msvc': 0.1.68 optional: true - '@napi-rs/wasm-runtime@0.2.10': - dependencies: - '@emnapi/core': 1.4.3 - '@emnapi/runtime': 1.4.3 - '@tybys/wasm-util': 0.9.0 - optional: true - '@neon-rs/load@0.0.4': {} '@noble/ciphers@0.6.0': {} @@ -10370,6 +10758,8 @@ snapshots: '@noble/hashes@1.7.1': {} + '@noble/hashes@1.8.0': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -10474,6 +10864,8 @@ snapshots: '@pkgr/core@0.1.1': {} + '@pkgr/core@0.2.7': {} + '@playwright/test@1.53.1': dependencies: playwright: 1.53.1 @@ -11089,25 +11481,23 @@ snapshots: dependencies: '@typescript-eslint/utils': 8.21.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) eslint: 9.27.0(jiti@2.4.2) - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 estraverse: 5.3.0 picomatch: 4.0.2 transitivePeerDependencies: - supports-color - typescript - '@stylistic/eslint-plugin@4.2.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': + '@stylistic/eslint-plugin@5.1.0(eslint@9.30.1(jiti@2.4.2))': dependencies: - '@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - eslint: 9.27.0(jiti@2.4.2) - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) + '@typescript-eslint/types': 8.35.1 + eslint: 9.30.1(jiti@2.4.2) + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 estraverse: 5.3.0 picomatch: 4.0.2 - transitivePeerDependencies: - - supports-color - - typescript '@swc/helpers@0.5.15': dependencies: @@ -11131,11 +11521,6 @@ snapshots: '@trysound/sax@0.2.0': {} - '@tybys/wasm-util@0.9.0': - dependencies: - tslib: 2.8.1 - optional: true - '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.27.2 @@ -11161,10 +11546,16 @@ snapshots: dependencies: '@types/node': 22.15.21 + '@types/chai@5.2.2': + dependencies: + '@types/deep-eql': 4.0.2 + '@types/debug@4.1.12': dependencies: '@types/ms': 0.7.34 + '@types/deep-eql@4.0.2': {} + '@types/doctrine@0.0.9': {} '@types/eslint@9.6.1': @@ -11178,9 +11569,11 @@ snapshots: '@types/estree@1.0.7': {} + '@types/estree@1.0.8': {} + '@types/fontkit@2.0.8': dependencies: - '@types/node': 22.15.21 + '@types/node': 24.0.10 '@types/hast@3.0.4': dependencies: @@ -11220,6 +11613,14 @@ snapshots: dependencies: undici-types: 6.21.0 + '@types/node@22.16.0': + dependencies: + undici-types: 6.21.0 + + '@types/node@24.0.10': + dependencies: + undici-types: 7.8.0 + '@types/nodemailer@6.4.17': dependencies: '@types/node': 22.15.21 @@ -11238,7 +11639,7 @@ snapshots: '@types/sax@1.2.7': dependencies: - '@types/node': 22.15.21 + '@types/node': 17.0.45 '@types/unist@2.0.11': {} @@ -11267,6 +11668,23 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/eslint-plugin@8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.35.1 + '@typescript-eslint/type-utils': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.35.1 + eslint: 9.30.1(jiti@2.4.2) + graphemer: 1.4.0 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@typescript-eslint/scope-manager': 8.32.1 @@ -11279,6 +11697,27 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.35.1 + '@typescript-eslint/types': 8.35.1 + '@typescript-eslint/typescript-estree': 8.35.1(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.35.1 + debug: 4.4.1 + eslint: 9.30.1(jiti@2.4.2) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.35.1(typescript@5.8.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.35.1(typescript@5.8.3) + '@typescript-eslint/types': 8.35.1 + debug: 4.4.1 + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/scope-manager@8.19.1': dependencies: '@typescript-eslint/types': 8.19.1 @@ -11299,6 +11738,15 @@ snapshots: '@typescript-eslint/types': 8.32.1 '@typescript-eslint/visitor-keys': 8.32.1 + '@typescript-eslint/scope-manager@8.35.1': + dependencies: + '@typescript-eslint/types': 8.35.1 + '@typescript-eslint/visitor-keys': 8.35.1 + + '@typescript-eslint/tsconfig-utils@8.35.1(typescript@5.8.3)': + dependencies: + typescript: 5.8.3 + '@typescript-eslint/type-utils@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.8.3) @@ -11310,6 +11758,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/type-utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@typescript-eslint/typescript-estree': 8.35.1(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + debug: 4.4.1 + eslint: 9.30.1(jiti@2.4.2) + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/types@8.19.1': {} '@typescript-eslint/types@8.21.0': {} @@ -11318,6 +11777,8 @@ snapshots: '@typescript-eslint/types@8.32.1': {} + '@typescript-eslint/types@8.35.1': {} + '@typescript-eslint/typescript-estree@8.19.1(typescript@5.8.3)': dependencies: '@typescript-eslint/types': 8.19.1 @@ -11350,7 +11811,7 @@ snapshots: dependencies: '@typescript-eslint/types': 8.26.1 '@typescript-eslint/visitor-keys': 8.26.1 - debug: 4.4.1 + debug: 4.4.0 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 @@ -11374,6 +11835,22 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/typescript-estree@8.35.1(typescript@5.8.3)': + dependencies: + '@typescript-eslint/project-service': 8.35.1(typescript@5.8.3) + '@typescript-eslint/tsconfig-utils': 8.35.1(typescript@5.8.3) + '@typescript-eslint/types': 8.35.1 + '@typescript-eslint/visitor-keys': 8.35.1 + debug: 4.4.1 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.2 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/utils@8.19.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@eslint-community/eslint-utils': 4.7.0(eslint@9.27.0(jiti@2.4.2)) @@ -11407,47 +11884,74 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/utils@8.35.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.27.0(jiti@2.4.2)) + '@typescript-eslint/scope-manager': 8.35.1 + '@typescript-eslint/types': 8.35.1 + '@typescript-eslint/typescript-estree': 8.35.1(typescript@5.8.3) + eslint: 9.27.0(jiti@2.4.2) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) + '@typescript-eslint/scope-manager': 8.35.1 + '@typescript-eslint/types': 8.35.1 + '@typescript-eslint/typescript-estree': 8.35.1(typescript@5.8.3) + eslint: 9.30.1(jiti@2.4.2) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/visitor-keys@8.19.1': dependencies: '@typescript-eslint/types': 8.19.1 - eslint-visitor-keys: 4.2.0 + eslint-visitor-keys: 4.2.1 '@typescript-eslint/visitor-keys@8.21.0': dependencies: '@typescript-eslint/types': 8.21.0 - eslint-visitor-keys: 4.2.0 + eslint-visitor-keys: 4.2.1 '@typescript-eslint/visitor-keys@8.26.1': dependencies: '@typescript-eslint/types': 8.26.1 - eslint-visitor-keys: 4.2.0 + eslint-visitor-keys: 4.2.1 '@typescript-eslint/visitor-keys@8.32.1': dependencies: '@typescript-eslint/types': 8.32.1 - eslint-visitor-keys: 4.2.0 + eslint-visitor-keys: 4.2.1 + + '@typescript-eslint/visitor-keys@8.35.1': + dependencies: + '@typescript-eslint/types': 8.35.1 + eslint-visitor-keys: 4.2.1 '@ungap/structured-clone@1.3.0': {} - '@unocss/astro@0.65.0-beta.2(rollup@4.39.0)(vite@5.4.19(@types/node@22.15.21))(vue@3.5.13(typescript@5.8.3))': + '@unocss/astro@0.65.0-beta.2(rollup@4.39.0)(vite@5.4.19(@types/node@22.16.0))(vue@3.5.13(typescript@5.8.3))': dependencies: '@unocss/core': 0.65.0-beta.2 '@unocss/reset': 0.65.0-beta.2 - '@unocss/vite': 0.65.0-beta.2(rollup@4.39.0)(vite@5.4.19(@types/node@22.15.21))(vue@3.5.13(typescript@5.8.3)) + '@unocss/vite': 0.65.0-beta.2(rollup@4.39.0)(vite@5.4.19(@types/node@22.16.0))(vue@3.5.13(typescript@5.8.3)) optionalDependencies: - vite: 5.4.19(@types/node@22.15.21) + vite: 5.4.19(@types/node@22.16.0) transitivePeerDependencies: - rollup - supports-color - vue - '@unocss/astro@0.65.0-beta.2(rollup@4.39.0)(vite@6.3.4(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3))': + '@unocss/astro@0.65.0-beta.2(rollup@4.39.0)(vite@6.3.4(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3))': dependencies: '@unocss/core': 0.65.0-beta.2 '@unocss/reset': 0.65.0-beta.2 - '@unocss/vite': 0.65.0-beta.2(rollup@4.39.0)(vite@6.3.4(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3)) + '@unocss/vite': 0.65.0-beta.2(rollup@4.39.0)(vite@6.3.4(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3)) optionalDependencies: - vite: 6.3.4(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.4(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - rollup - supports-color @@ -11589,7 +12093,7 @@ snapshots: dependencies: '@unocss/core': 0.65.0-beta.2 - '@unocss/vite@0.65.0-beta.2(rollup@4.39.0)(vite@5.4.19(@types/node@22.15.21))(vue@3.5.13(typescript@5.8.3))': + '@unocss/vite@0.65.0-beta.2(rollup@4.39.0)(vite@5.4.19(@types/node@22.16.0))(vue@3.5.13(typescript@5.8.3))': dependencies: '@ampproject/remapping': 2.3.0 '@rollup/pluginutils': 5.1.4(rollup@4.39.0) @@ -11599,13 +12103,13 @@ snapshots: chokidar: 3.6.0 magic-string: 0.30.17 tinyglobby: 0.2.14 - vite: 5.4.19(@types/node@22.15.21) + vite: 5.4.19(@types/node@22.16.0) transitivePeerDependencies: - rollup - supports-color - vue - '@unocss/vite@0.65.0-beta.2(rollup@4.39.0)(vite@6.3.4(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3))': + '@unocss/vite@0.65.0-beta.2(rollup@4.39.0)(vite@6.3.4(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3))': dependencies: '@ampproject/remapping': 2.3.0 '@rollup/pluginutils': 5.1.4(rollup@4.39.0) @@ -11615,65 +12119,12 @@ snapshots: chokidar: 3.6.0 magic-string: 0.30.17 tinyglobby: 0.2.14 - vite: 6.3.4(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.4(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - rollup - supports-color - vue - '@unrs/resolver-binding-darwin-arm64@1.7.2': - optional: true - - '@unrs/resolver-binding-darwin-x64@1.7.2': - optional: true - - '@unrs/resolver-binding-freebsd-x64@1.7.2': - optional: true - - '@unrs/resolver-binding-linux-arm-gnueabihf@1.7.2': - optional: true - - '@unrs/resolver-binding-linux-arm-musleabihf@1.7.2': - optional: true - - '@unrs/resolver-binding-linux-arm64-gnu@1.7.2': - optional: true - - '@unrs/resolver-binding-linux-arm64-musl@1.7.2': - optional: true - - '@unrs/resolver-binding-linux-ppc64-gnu@1.7.2': - optional: true - - '@unrs/resolver-binding-linux-riscv64-gnu@1.7.2': - optional: true - - '@unrs/resolver-binding-linux-riscv64-musl@1.7.2': - optional: true - - '@unrs/resolver-binding-linux-s390x-gnu@1.7.2': - optional: true - - '@unrs/resolver-binding-linux-x64-gnu@1.7.2': - optional: true - - '@unrs/resolver-binding-linux-x64-musl@1.7.2': - optional: true - - '@unrs/resolver-binding-wasm32-wasi@1.7.2': - dependencies: - '@napi-rs/wasm-runtime': 0.2.10 - optional: true - - '@unrs/resolver-binding-win32-arm64-msvc@1.7.2': - optional: true - - '@unrs/resolver-binding-win32-ia32-msvc@1.7.2': - optional: true - - '@unrs/resolver-binding-win32-x64-msvc@1.7.2': - optional: true - '@vitest/coverage-v8@3.1.3(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@26.0.0))': dependencies: '@ampproject/remapping': 2.3.0 @@ -11692,34 +12143,73 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitest/eslint-plugin@1.1.25(@typescript-eslint/utils@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jiti@2.4.2)(jsdom@26.0.0)(tsx@4.20.3)(yaml@2.8.0))': + '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(jsdom@26.0.0))': dependencies: - '@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - eslint: 9.27.0(jiti@2.4.2) - optionalDependencies: - typescript: 5.8.3 - vitest: 3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jiti@2.4.2)(jsdom@26.0.0)(tsx@4.20.3)(yaml@2.8.0) - - '@vitest/eslint-plugin@1.2.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@25.0.1(canvas@2.11.2)))': - dependencies: - '@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - eslint: 9.27.0(jiti@2.4.2) - optionalDependencies: - typescript: 5.8.3 - vitest: 3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@25.0.1(canvas@2.11.2)) + '@ampproject/remapping': 2.3.0 + '@bcoe/v8-coverage': 1.0.2 + ast-v8-to-istanbul: 0.3.3 + debug: 4.4.1 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.1.7 + magic-string: 0.30.17 + magicast: 0.3.5 + std-env: 3.9.0 + test-exclude: 7.0.1 + tinyrainbow: 2.0.0 + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(jsdom@26.0.0) transitivePeerDependencies: - supports-color - '@vitest/eslint-plugin@1.2.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@26.0.0))': + '@vitest/eslint-plugin@1.1.25(@typescript-eslint/utils@8.35.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.0.10)(jsdom@26.0.0))': dependencies: - '@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) eslint: 9.27.0(jiti@2.4.2) + optionalDependencies: + typescript: 5.8.3 + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.0.10)(jsdom@26.0.0) + + '@vitest/eslint-plugin@1.3.4(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@26.0.0))': + dependencies: + '@typescript-eslint/utils': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.30.1(jiti@2.4.2) optionalDependencies: typescript: 5.8.3 vitest: 3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@26.0.0) transitivePeerDependencies: - supports-color + '@vitest/eslint-plugin@1.3.4(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(jsdom@25.0.1(canvas@2.11.2)))': + dependencies: + '@typescript-eslint/utils': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.30.1(jiti@2.4.2) + optionalDependencies: + typescript: 5.8.3 + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(jsdom@25.0.1(canvas@2.11.2)) + transitivePeerDependencies: + - supports-color + + '@vitest/eslint-plugin@1.3.4(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(jsdom@26.0.0))': + dependencies: + '@typescript-eslint/utils': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.30.1(jiti@2.4.2) + optionalDependencies: + typescript: 5.8.3 + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(jsdom@26.0.0) + transitivePeerDependencies: + - supports-color + + '@vitest/eslint-plugin@1.3.4(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.0.10)(jsdom@26.0.0))': + dependencies: + '@typescript-eslint/utils': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.30.1(jiti@2.4.2) + optionalDependencies: + typescript: 5.8.3 + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.0.10)(jsdom@26.0.0) + transitivePeerDependencies: + - supports-color + '@vitest/expect@3.1.3': dependencies: '@vitest/spy': 3.1.3 @@ -11727,6 +12217,14 @@ snapshots: chai: 5.2.0 tinyrainbow: 2.0.0 + '@vitest/expect@3.2.4': + dependencies: + '@types/chai': 5.2.2 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.2.0 + tinyrainbow: 2.0.0 + '@vitest/mocker@3.1.3(vite@5.4.19(@types/node@22.15.21))': dependencies: '@vitest/spy': 3.1.3 @@ -11735,43 +12233,76 @@ snapshots: optionalDependencies: vite: 5.4.19(@types/node@22.15.21) - '@vitest/mocker@3.1.3(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))': + '@vitest/mocker@3.2.4(vite@5.4.19(@types/node@22.16.0))': dependencies: - '@vitest/spy': 3.1.3 + '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.3.5(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0) - optional: true + vite: 5.4.19(@types/node@22.16.0) + + '@vitest/mocker@3.2.4(vite@5.4.19(@types/node@24.0.10))': + dependencies: + '@vitest/spy': 3.2.4 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + vite: 5.4.19(@types/node@24.0.10) '@vitest/pretty-format@3.1.3': dependencies: tinyrainbow: 2.0.0 + '@vitest/pretty-format@3.2.4': + dependencies: + tinyrainbow: 2.0.0 + '@vitest/runner@3.1.3': dependencies: '@vitest/utils': 3.1.3 pathe: 2.0.3 + '@vitest/runner@3.2.4': + dependencies: + '@vitest/utils': 3.2.4 + pathe: 2.0.3 + strip-literal: 3.0.0 + '@vitest/snapshot@3.1.3': dependencies: '@vitest/pretty-format': 3.1.3 magic-string: 0.30.17 pathe: 2.0.3 + '@vitest/snapshot@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + magic-string: 0.30.17 + pathe: 2.0.3 + '@vitest/spy@3.1.3': dependencies: tinyspy: 3.0.2 + '@vitest/spy@3.2.4': + dependencies: + tinyspy: 4.0.3 + '@vitest/utils@3.1.3': dependencies: '@vitest/pretty-format': 3.1.3 loupe: 3.1.3 tinyrainbow: 2.0.0 + '@vitest/utils@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + loupe: 3.1.4 + tinyrainbow: 2.0.0 + '@vue/compiler-core@3.5.13': dependencies: - '@babel/parser': 7.27.5 + '@babel/parser': 7.28.0 '@vue/shared': 3.5.13 entities: 4.5.0 estree-walker: 2.0.2 @@ -11784,7 +12315,7 @@ snapshots: '@vue/compiler-sfc@3.5.13': dependencies: - '@babel/parser': 7.27.5 + '@babel/parser': 7.28.0 '@vue/compiler-core': 3.5.13 '@vue/compiler-dom': 3.5.13 '@vue/compiler-ssr': 3.5.13 @@ -11830,8 +12361,14 @@ snapshots: dependencies: acorn: 8.14.1 + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn@8.14.1: {} + acorn@8.15.0: {} + agent-base@6.0.2: dependencies: debug: 4.4.1 @@ -11875,7 +12412,7 @@ snapshots: ansi-styles@6.2.1: {} - ansis@4.0.0: {} + ansis@4.1.0: {} anymatch@3.1.3: dependencies: @@ -11915,6 +12452,12 @@ snapshots: assertion-error@2.0.1: {} + ast-v8-to-istanbul@0.3.3: + dependencies: + '@jridgewell/trace-mapping': 0.3.29 + estree-walker: 3.0.3 + js-tokens: 9.0.1 + astring@1.9.0: {} astro-eslint-parser@1.1.0(typescript@5.8.3): @@ -11926,9 +12469,9 @@ snapshots: astrojs-compiler-sync: 1.0.1(@astrojs/compiler@2.11.0) debug: 4.4.0 entities: 4.5.0 - eslint-scope: 8.3.0 - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 globby: 11.1.0 is-glob: 4.0.3 semver: 7.7.1 @@ -11936,12 +12479,12 @@ snapshots: - supports-color - typescript - astro-expressive-code@0.41.2(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@22.15.21)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0)): + astro-expressive-code@0.41.2(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@24.0.10)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0)): dependencies: - astro: 5.8.0(@azure/storage-blob@12.27.0)(@types/node@22.15.21)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) + astro: 5.8.0(@azure/storage-blob@12.27.0)(@types/node@24.0.10)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) rehype-expressive-code: 0.41.2 - astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@22.15.21)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0): + astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@24.0.10)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0): dependencies: '@astrojs/compiler': 2.11.0 '@astrojs/internal-helpers': 0.6.1 @@ -11996,8 +12539,8 @@ snapshots: unist-util-visit: 5.0.0 unstorage: 1.16.0(@azure/storage-blob@12.27.0)(idb-keyval@6.2.1) vfile: 6.0.3 - vite: 6.3.4(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0) - vitefu: 1.0.6(vite@6.3.4(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0)) + vite: 6.3.4(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0) + vitefu: 1.0.6(vite@6.3.4(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0)) xxhash-wasm: 1.1.0 yargs-parser: 21.1.1 yocto-spinner: 0.2.1 @@ -12154,6 +12697,21 @@ snapshots: is-alphanumerical: 2.0.1 is-decimal: 2.0.1 + better-auth@1.2.12: + dependencies: + '@better-auth/utils': 0.2.5 + '@better-fetch/fetch': 1.1.18 + '@noble/ciphers': 0.6.0 + '@noble/hashes': 1.8.0 + '@simplewebauthn/browser': 13.1.0 + '@simplewebauthn/server': 13.1.1 + better-call: 1.0.11 + defu: 6.1.4 + jose: 6.0.11 + kysely: 0.28.2 + nanostores: 0.11.4 + zod: 3.25.73 + better-auth@1.2.8: dependencies: '@better-auth/utils': 0.2.5 @@ -12169,6 +12727,13 @@ snapshots: nanostores: 0.11.4 zod: 3.25.67 + better-call@1.0.11: + dependencies: + '@better-fetch/fetch': 1.1.18 + rou3: 0.5.1 + set-cookie-parser: 2.7.1 + uncrypto: 0.1.3 + better-call@1.0.9: dependencies: '@better-fetch/fetch': 1.1.18 @@ -12583,7 +13148,7 @@ snapshots: '@asamuzakjp/css-color': 3.1.7 rrweb-cssom: 0.8.0 - cssstyle@4.5.0: + cssstyle@4.6.0: dependencies: '@asamuzakjp/css-color': 3.2.0 rrweb-cssom: 0.8.0 @@ -12763,10 +13328,10 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.2.1 - enhanced-resolve@5.18.1: + enhanced-resolve@5.18.2: dependencies: graceful-fs: 4.2.11 - tapable: 2.2.1 + tapable: 2.2.2 enquirer@2.4.1: dependencies: @@ -12996,27 +13561,42 @@ snapshots: eslint: 9.27.0(jiti@2.4.2) semver: 7.7.2 + eslint-compat-utils@0.5.1(eslint@9.30.1(jiti@2.4.2)): + dependencies: + eslint: 9.30.1(jiti@2.4.2) + semver: 7.7.2 + eslint-compat-utils@0.6.4(eslint@9.27.0(jiti@2.4.2)): dependencies: eslint: 9.27.0(jiti@2.4.2) semver: 7.7.1 + eslint-compat-utils@0.6.4(eslint@9.30.1(jiti@2.4.2)): + dependencies: + eslint: 9.30.1(jiti@2.4.2) + semver: 7.7.1 + + eslint-compat-utils@0.6.5(eslint@9.30.1(jiti@2.4.2)): + dependencies: + eslint: 9.30.1(jiti@2.4.2) + semver: 7.7.2 + eslint-config-flat-gitignore@1.0.0(eslint@9.27.0(jiti@2.4.2)): dependencies: '@eslint/compat': 1.2.4(eslint@9.27.0(jiti@2.4.2)) eslint: 9.27.0(jiti@2.4.2) find-up-simple: 1.0.0 - eslint-config-flat-gitignore@2.1.0(eslint@9.27.0(jiti@2.4.2)): + eslint-config-flat-gitignore@2.1.0(eslint@9.30.1(jiti@2.4.2)): dependencies: - '@eslint/compat': 1.2.8(eslint@9.27.0(jiti@2.4.2)) - eslint: 9.27.0(jiti@2.4.2) + '@eslint/compat': 1.2.8(eslint@9.30.1(jiti@2.4.2)) + eslint: 9.30.1(jiti@2.4.2) eslint-flat-config-utils@1.1.0: dependencies: pathe: 2.0.3 - eslint-flat-config-utils@2.0.1: + eslint-flat-config-utils@2.1.0: dependencies: pathe: 2.0.3 @@ -13034,22 +13614,28 @@ snapshots: esquery: 1.6.0 jsonc-eslint-parser: 2.4.0 + eslint-json-compat-utils@0.2.1(eslint@9.30.1(jiti@2.4.2))(jsonc-eslint-parser@2.4.0): + dependencies: + eslint: 9.30.1(jiti@2.4.2) + esquery: 1.6.0 + jsonc-eslint-parser: 2.4.0 + eslint-merge-processors@1.0.0(eslint@9.27.0(jiti@2.4.2)): dependencies: eslint: 9.27.0(jiti@2.4.2) - eslint-merge-processors@2.0.0(eslint@9.27.0(jiti@2.4.2)): + eslint-merge-processors@2.0.0(eslint@9.30.1(jiti@2.4.2)): dependencies: - eslint: 9.27.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) eslint-plugin-antfu@2.7.0(eslint@9.27.0(jiti@2.4.2)): dependencies: '@antfu/utils': 0.7.10 eslint: 9.27.0(jiti@2.4.2) - eslint-plugin-antfu@3.1.1(eslint@9.27.0(jiti@2.4.2)): + eslint-plugin-antfu@3.1.1(eslint@9.30.1(jiti@2.4.2)): dependencies: - eslint: 9.27.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) eslint-plugin-astro@1.3.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3): dependencies: @@ -13066,15 +13652,31 @@ snapshots: - supports-color - typescript + eslint-plugin-astro@1.3.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3): + dependencies: + '@eslint-community/eslint-utils': 4.5.1(eslint@9.30.1(jiti@2.4.2)) + '@jridgewell/sourcemap-codec': 1.5.0 + '@typescript-eslint/types': 8.26.1 + astro-eslint-parser: 1.1.0(typescript@5.8.3) + eslint: 9.30.1(jiti@2.4.2) + eslint-compat-utils: 0.6.4(eslint@9.30.1(jiti@2.4.2)) + globals: 15.15.0 + postcss: 8.5.3 + postcss-selector-parser: 7.0.0 + transitivePeerDependencies: + - supports-color + - typescript + optional: true + eslint-plugin-command@2.1.0(eslint@9.27.0(jiti@2.4.2)): dependencies: '@es-joy/jsdoccomment': 0.50.0 eslint: 9.27.0(jiti@2.4.2) - eslint-plugin-command@3.2.0(eslint@9.27.0(jiti@2.4.2)): + eslint-plugin-command@3.3.1(eslint@9.30.1(jiti@2.4.2)): dependencies: - '@es-joy/jsdoccomment': 0.50.1 - eslint: 9.27.0(jiti@2.4.2) + '@es-joy/jsdoccomment': 0.50.2 + eslint: 9.30.1(jiti@2.4.2) eslint-plugin-es-x@7.8.0(eslint@9.27.0(jiti@2.4.2)): dependencies: @@ -13083,23 +13685,20 @@ snapshots: eslint: 9.27.0(jiti@2.4.2) eslint-compat-utils: 0.5.1(eslint@9.27.0(jiti@2.4.2)) - eslint-plugin-import-x@4.12.2(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3): + eslint-plugin-es-x@7.8.0(eslint@9.30.1(jiti@2.4.2)): dependencies: - '@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - comment-parser: 1.4.1 - debug: 4.4.1 - eslint: 9.27.0(jiti@2.4.2) - eslint-import-resolver-node: 0.3.9 - get-tsconfig: 4.10.0 - is-glob: 4.0.3 - minimatch: 10.0.1 - semver: 7.7.2 - stable-hash: 0.0.5 - tslib: 2.8.1 - unrs-resolver: 1.7.2 - transitivePeerDependencies: - - supports-color - - typescript + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) + '@eslint-community/regexpp': 4.12.1 + eslint: 9.30.1(jiti@2.4.2) + eslint-compat-utils: 0.5.1(eslint@9.30.1(jiti@2.4.2)) + + eslint-plugin-import-lite@0.3.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3): + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) + '@typescript-eslint/types': 8.35.1 + eslint: 9.30.1(jiti@2.4.2) + optionalDependencies: + typescript: 5.8.3 eslint-plugin-import-x@4.6.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3): dependencies: @@ -13129,7 +13728,23 @@ snapshots: debug: 4.4.1 escape-string-regexp: 4.0.0 eslint: 9.27.0(jiti@2.4.2) - espree: 10.3.0 + espree: 10.4.0 + esquery: 1.6.0 + parse-imports-exports: 0.2.4 + semver: 7.7.2 + spdx-expression-parse: 4.0.0 + transitivePeerDependencies: + - supports-color + + eslint-plugin-jsdoc@51.3.3(eslint@9.30.1(jiti@2.4.2)): + dependencies: + '@es-joy/jsdoccomment': 0.52.0 + are-docs-informative: 0.0.2 + comment-parser: 1.4.1 + debug: 4.4.1 + escape-string-regexp: 4.0.0 + eslint: 9.30.1(jiti@2.4.2) + espree: 10.4.0 esquery: 1.6.0 parse-imports-exports: 0.2.4 semver: 7.7.2 @@ -13151,17 +13766,17 @@ snapshots: transitivePeerDependencies: - '@eslint/json' - eslint-plugin-jsonc@2.20.0(eslint@9.27.0(jiti@2.4.2)): + eslint-plugin-jsonc@2.20.1(eslint@9.30.1(jiti@2.4.2)): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.27.0(jiti@2.4.2)) - eslint: 9.27.0(jiti@2.4.2) - eslint-compat-utils: 0.6.4(eslint@9.27.0(jiti@2.4.2)) - eslint-json-compat-utils: 0.2.1(eslint@9.27.0(jiti@2.4.2))(jsonc-eslint-parser@2.4.0) - espree: 10.3.0 + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) + eslint: 9.30.1(jiti@2.4.2) + eslint-compat-utils: 0.6.5(eslint@9.30.1(jiti@2.4.2)) + eslint-json-compat-utils: 0.2.1(eslint@9.30.1(jiti@2.4.2))(jsonc-eslint-parser@2.4.0) + espree: 10.4.0 graphemer: 1.4.0 jsonc-eslint-parser: 2.4.0 natural-compare: 1.4.0 - synckit: 0.6.2 + synckit: 0.11.8 transitivePeerDependencies: - '@eslint/json' @@ -13177,17 +13792,20 @@ snapshots: minimatch: 9.0.5 semver: 7.7.2 - eslint-plugin-n@17.18.0(eslint@9.27.0(jiti@2.4.2)): + eslint-plugin-n@17.21.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.27.0(jiti@2.4.2)) - enhanced-resolve: 5.18.1 - eslint: 9.27.0(jiti@2.4.2) - eslint-plugin-es-x: 7.8.0(eslint@9.27.0(jiti@2.4.2)) - get-tsconfig: 4.10.0 + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) + enhanced-resolve: 5.18.2 + eslint: 9.30.1(jiti@2.4.2) + eslint-plugin-es-x: 7.8.0(eslint@9.30.1(jiti@2.4.2)) + get-tsconfig: 4.10.1 globals: 15.15.0 ignore: 5.3.2 minimatch: 9.0.5 semver: 7.7.2 + ts-declaration-location: 1.0.7(typescript@5.8.3) + transitivePeerDependencies: + - typescript eslint-plugin-no-only-tests@3.3.0: {} @@ -13201,9 +13819,19 @@ snapshots: - supports-color - typescript - eslint-plugin-pnpm@0.3.1(eslint@9.27.0(jiti@2.4.2)): + eslint-plugin-perfectionist@4.15.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3): dependencies: - eslint: 9.27.0(jiti@2.4.2) + '@typescript-eslint/types': 8.35.1 + '@typescript-eslint/utils': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.30.1(jiti@2.4.2) + natural-orderby: 5.0.0 + transitivePeerDependencies: + - supports-color + - typescript + + eslint-plugin-pnpm@0.3.1(eslint@9.30.1(jiti@2.4.2)): + dependencies: + eslint: 9.30.1(jiti@2.4.2) find-up-simple: 1.0.1 jsonc-eslint-parser: 2.4.0 pathe: 2.0.3 @@ -13222,6 +13850,17 @@ snapshots: regexp-ast-analysis: 0.7.1 scslre: 0.3.0 + eslint-plugin-regexp@2.9.0(eslint@9.30.1(jiti@2.4.2)): + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) + '@eslint-community/regexpp': 4.12.1 + comment-parser: 1.4.1 + eslint: 9.30.1(jiti@2.4.2) + jsdoc-type-pratt-parser: 4.1.0 + refa: 0.12.1 + regexp-ast-analysis: 0.7.1 + scslre: 0.3.0 + eslint-plugin-toml@0.12.0(eslint@9.27.0(jiti@2.4.2)): dependencies: debug: 4.4.1 @@ -13232,6 +13871,16 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-plugin-toml@0.12.0(eslint@9.30.1(jiti@2.4.2)): + dependencies: + debug: 4.4.1 + eslint: 9.30.1(jiti@2.4.2) + eslint-compat-utils: 0.6.4(eslint@9.30.1(jiti@2.4.2)) + lodash: 4.17.21 + toml-eslint-parser: 0.10.0 + transitivePeerDependencies: + - supports-color + eslint-plugin-unicorn@56.0.1(eslint@9.27.0(jiti@2.4.2)): dependencies: '@babel/helper-validator-identifier': 7.25.9 @@ -13252,18 +13901,18 @@ snapshots: semver: 7.7.2 strip-indent: 3.0.0 - eslint-plugin-unicorn@59.0.1(eslint@9.27.0(jiti@2.4.2)): + eslint-plugin-unicorn@59.0.1(eslint@9.30.1(jiti@2.4.2)): dependencies: '@babel/helper-validator-identifier': 7.27.1 - '@eslint-community/eslint-utils': 4.7.0(eslint@9.27.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) '@eslint/plugin-kit': 0.2.8 ci-info: 4.2.0 clean-regexp: 1.0.0 core-js-compat: 3.42.0 - eslint: 9.27.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) esquery: 1.6.0 find-up-simple: 1.0.1 - globals: 16.1.0 + globals: 16.3.0 indent-string: 5.0.0 is-builtin-module: 5.0.0 jsesc: 3.1.0 @@ -13279,16 +13928,24 @@ snapshots: optionalDependencies: '@typescript-eslint/eslint-plugin': 8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - eslint-plugin-vue@10.1.0(eslint@9.27.0(jiti@2.4.2))(vue-eslint-parser@10.1.3(eslint@9.27.0(jiti@2.4.2))): + eslint-plugin-unused-imports@4.1.4(@typescript-eslint/eslint-plugin@8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2)): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.27.0(jiti@2.4.2)) - eslint: 9.27.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) + optionalDependencies: + '@typescript-eslint/eslint-plugin': 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + + eslint-plugin-vue@10.3.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(vue-eslint-parser@10.2.0(eslint@9.30.1(jiti@2.4.2))): + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) + eslint: 9.30.1(jiti@2.4.2) natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 6.1.2 semver: 7.7.2 - vue-eslint-parser: 10.1.3(eslint@9.27.0(jiti@2.4.2)) + vue-eslint-parser: 10.2.0(eslint@9.30.1(jiti@2.4.2)) xml-name-validator: 4.0.0 + optionalDependencies: + '@typescript-eslint/parser': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) eslint-plugin-vue@9.32.0(eslint@9.27.0(jiti@2.4.2)): dependencies: @@ -13315,12 +13972,12 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-yml@1.18.0(eslint@9.27.0(jiti@2.4.2)): + eslint-plugin-yml@1.18.0(eslint@9.30.1(jiti@2.4.2)): dependencies: debug: 4.4.1 escape-string-regexp: 4.0.0 - eslint: 9.27.0(jiti@2.4.2) - eslint-compat-utils: 0.6.4(eslint@9.27.0(jiti@2.4.2)) + eslint: 9.30.1(jiti@2.4.2) + eslint-compat-utils: 0.6.4(eslint@9.30.1(jiti@2.4.2)) natural-compare: 1.4.0 yaml-eslint-parser: 1.3.0 transitivePeerDependencies: @@ -13331,10 +13988,10 @@ snapshots: '@vue/compiler-sfc': 3.5.13 eslint: 9.27.0(jiti@2.4.2) - eslint-processor-vue-blocks@2.0.0(@vue/compiler-sfc@3.5.13)(eslint@9.27.0(jiti@2.4.2)): + eslint-processor-vue-blocks@2.0.0(@vue/compiler-sfc@3.5.13)(eslint@9.30.1(jiti@2.4.2)): dependencies: '@vue/compiler-sfc': 3.5.13 - eslint: 9.27.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) eslint-scope@7.2.2: dependencies: @@ -13346,10 +14003,17 @@ snapshots: esrecurse: 4.3.0 estraverse: 5.3.0 + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + eslint-visitor-keys@3.4.3: {} eslint-visitor-keys@4.2.0: {} + eslint-visitor-keys@4.2.1: {} + eslint@9.27.0(jiti@2.4.2): dependencies: '@eslint-community/eslint-utils': 4.7.0(eslint@9.27.0(jiti@2.4.2)) @@ -13392,16 +14056,64 @@ snapshots: transitivePeerDependencies: - supports-color + eslint@9.30.1(jiti@2.4.2): + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.21.0 + '@eslint/config-helpers': 0.3.0 + '@eslint/core': 0.14.0 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.30.1 + '@eslint/plugin-kit': 0.3.1 + '@humanfs/node': 0.16.6 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.2 + '@types/estree': 1.0.7 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.1 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.4.2 + transitivePeerDependencies: + - supports-color + espree@10.3.0: dependencies: acorn: 8.14.1 acorn-jsx: 5.3.2(acorn@8.14.1) eslint-visitor-keys: 4.2.0 + espree@10.4.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 + espree@9.6.1: dependencies: - acorn: 8.14.1 - acorn-jsx: 5.3.2(acorn@8.14.1) + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) eslint-visitor-keys: 3.4.3 esprima@4.0.1: {} @@ -13697,6 +14409,10 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 + get-tsconfig@4.10.1: + dependencies: + resolve-pkg-maps: 1.0.0 + giget@2.0.0: dependencies: citty: 0.1.6 @@ -13749,7 +14465,7 @@ snapshots: globals@15.15.0: {} - globals@16.1.0: {} + globals@16.3.0: {} globby@11.1.0: dependencies: @@ -14069,6 +14785,8 @@ snapshots: ignore@7.0.4: {} + ignore@7.0.5: {} + import-fresh@3.3.1: dependencies: parent-module: 1.0.1 @@ -14224,10 +14942,14 @@ snapshots: jose@5.10.0: {} + jose@6.0.11: {} + js-base64@3.7.7: {} js-tokens@4.0.0: {} + js-tokens@9.0.1: {} + js-yaml@3.14.1: dependencies: argparse: 1.0.10 @@ -14271,7 +14993,7 @@ snapshots: jsdom@26.0.0: dependencies: - cssstyle: 4.5.0 + cssstyle: 4.6.0 data-urls: 5.0.0 decimal.js: 10.5.0 form-data: 4.0.3 @@ -14290,7 +15012,7 @@ snapshots: whatwg-encoding: 3.1.1 whatwg-mimetype: 4.0.0 whatwg-url: 14.2.0 - ws: 8.18.2 + ws: 8.18.3 xml-name-validator: 5.0.0 transitivePeerDependencies: - bufferutil @@ -14320,7 +15042,7 @@ snapshots: jsonc-eslint-parser@2.4.0: dependencies: - acorn: 8.14.1 + acorn: 8.15.0 eslint-visitor-keys: 3.4.3 espree: 9.6.1 semver: 7.7.2 @@ -14410,6 +15132,8 @@ snapshots: loupe@3.1.3: {} + loupe@3.1.4: {} + lru-cache@10.4.3: {} lru-cache@5.1.1: @@ -14695,7 +15419,7 @@ snapshots: micromark-util-resolve-all: 2.0.1 micromark-util-subtokenize: 2.0.3 micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + micromark-util-types: 2.0.1 micromark-core-commonmark@2.0.3: dependencies: @@ -14846,14 +15570,14 @@ snapshots: dependencies: micromark-util-character: 2.1.1 micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + micromark-util-types: 2.0.1 micromark-factory-label@2.0.1: dependencies: devlop: 1.1.0 micromark-util-character: 2.1.1 micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + micromark-util-types: 2.0.1 micromark-factory-mdx-expression@2.0.3: dependencies: @@ -14877,7 +15601,7 @@ snapshots: micromark-factory-space: 2.0.1 micromark-util-character: 2.1.1 micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + micromark-util-types: 2.0.1 micromark-factory-whitespace@2.0.1: dependencies: @@ -14937,7 +15661,7 @@ snapshots: micromark-util-resolve-all@2.0.1: dependencies: - micromark-util-types: 2.0.2 + micromark-util-types: 2.0.1 micromark-util-sanitize-uri@2.0.1: dependencies: @@ -14950,7 +15674,7 @@ snapshots: devlop: 1.1.0 micromark-util-chunked: 2.0.1 micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + micromark-util-types: 2.0.1 micromark-util-subtokenize@2.1.0: dependencies: @@ -15015,10 +15739,6 @@ snapshots: min-indent@1.0.1: {} - minimatch@10.0.1: - dependencies: - brace-expansion: 2.0.1 - minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -15071,7 +15791,7 @@ snapshots: mlly@1.7.3: dependencies: - acorn: 8.14.1 + acorn: 8.15.0 pathe: 1.1.2 pkg-types: 1.3.1 ufo: 1.6.1 @@ -15102,8 +15822,6 @@ snapshots: napi-build-utils@2.0.0: {} - napi-postinstall@0.2.4: {} - natural-compare@1.4.0: {} natural-orderby@5.0.0: {} @@ -16234,13 +16952,11 @@ snapshots: stable-hash@0.0.4: {} - stable-hash@0.0.5: {} - stackback@0.0.2: {} - starlight-links-validator@0.16.0(@astrojs/starlight@0.34.3(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@22.15.21)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))): + starlight-links-validator@0.16.0(@astrojs/starlight@0.34.3(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@24.0.10)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))): dependencies: - '@astrojs/starlight': 0.34.3(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@22.15.21)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0)) + '@astrojs/starlight': 0.34.3(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@24.0.10)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0)) '@types/picomatch': 3.0.2 github-slugger: 2.0.0 hast-util-from-html: 2.0.3 @@ -16254,9 +16970,9 @@ snapshots: transitivePeerDependencies: - supports-color - starlight-theme-rapide@0.5.1(@astrojs/starlight@0.34.3(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@22.15.21)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))): + starlight-theme-rapide@0.5.1(@astrojs/starlight@0.34.3(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@24.0.10)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))): dependencies: - '@astrojs/starlight': 0.34.3(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@22.15.21)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0)) + '@astrojs/starlight': 0.34.3(astro@5.8.0(@azure/storage-blob@12.27.0)(@types/node@24.0.10)(idb-keyval@6.2.1)(jiti@2.4.2)(rollup@4.39.0)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0)) std-env@3.9.0: {} @@ -16323,6 +17039,10 @@ snapshots: strip-json-comments@3.1.1: {} + strip-literal@3.0.0: + dependencies: + js-tokens: 9.0.1 + stripe@17.7.0: dependencies: '@types/node': 22.15.21 @@ -16366,6 +17086,10 @@ snapshots: symbol-tree@3.2.4: {} + synckit@0.11.8: + dependencies: + '@pkgr/core': 0.2.7 + synckit@0.6.2: dependencies: tslib: 2.8.1 @@ -16379,6 +17103,8 @@ snapshots: tapable@2.2.1: {} + tapable@2.2.2: {} + tar-fs@2.1.2: dependencies: chownr: 1.1.4 @@ -16472,10 +17198,14 @@ snapshots: tinypool@1.0.2: {} + tinypool@1.1.1: {} + tinyrainbow@2.0.0: {} tinyspy@3.0.2: {} + tinyspy@4.0.3: {} + tldts-core@6.1.84: {} tldts@6.1.84: @@ -16518,6 +17248,11 @@ snapshots: dependencies: typescript: 5.8.3 + ts-declaration-location@1.0.7(typescript@5.8.3): + dependencies: + picomatch: 4.0.2 + typescript: 5.8.3 + ts-pattern@5.7.1: {} tsconfck@3.1.5(typescript@5.8.3): @@ -16616,6 +17351,8 @@ snapshots: undici-types@6.21.0: {} + undici-types@7.8.0: {} + unicode-properties@1.4.1: dependencies: base64-js: 1.5.1 @@ -16689,17 +17426,17 @@ snapshots: universalify@0.1.2: {} - unocss-preset-animations@1.2.1(unocss@0.65.0-beta.2(postcss@8.5.3)(rollup@4.39.0)(vite@6.3.4(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3))): + unocss-preset-animations@1.2.1(unocss@0.65.0-beta.2(postcss@8.5.3)(rollup@4.39.0)(vite@6.3.4(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3))): dependencies: - unocss: 0.65.0-beta.2(postcss@8.5.3)(rollup@4.39.0)(vite@6.3.4(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3)) + unocss: 0.65.0-beta.2(postcss@8.5.3)(rollup@4.39.0)(vite@6.3.4(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3)) - unocss-preset-animations@1.2.1(unocss@0.65.0-beta.2(postcss@8.5.6)(rollup@4.39.0)(vite@5.4.19(@types/node@22.15.21))(vue@3.5.13(typescript@5.8.3))): + unocss-preset-animations@1.2.1(unocss@0.65.0-beta.2(postcss@8.5.6)(rollup@4.39.0)(vite@5.4.19(@types/node@22.16.0))(vue@3.5.13(typescript@5.8.3))): dependencies: - unocss: 0.65.0-beta.2(postcss@8.5.6)(rollup@4.39.0)(vite@5.4.19(@types/node@22.15.21))(vue@3.5.13(typescript@5.8.3)) + unocss: 0.65.0-beta.2(postcss@8.5.6)(rollup@4.39.0)(vite@5.4.19(@types/node@22.16.0))(vue@3.5.13(typescript@5.8.3)) - unocss@0.65.0-beta.2(postcss@8.5.3)(rollup@4.39.0)(vite@6.3.4(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3)): + unocss@0.65.0-beta.2(postcss@8.5.3)(rollup@4.39.0)(vite@6.3.4(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3)): dependencies: - '@unocss/astro': 0.65.0-beta.2(rollup@4.39.0)(vite@6.3.4(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3)) + '@unocss/astro': 0.65.0-beta.2(rollup@4.39.0)(vite@6.3.4(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3)) '@unocss/cli': 0.65.0-beta.2(rollup@4.39.0) '@unocss/core': 0.65.0-beta.2 '@unocss/postcss': 0.65.0-beta.2(postcss@8.5.3) @@ -16715,18 +17452,18 @@ snapshots: '@unocss/transformer-compile-class': 0.65.0-beta.2 '@unocss/transformer-directives': 0.65.0-beta.2 '@unocss/transformer-variant-group': 0.65.0-beta.2 - '@unocss/vite': 0.65.0-beta.2(rollup@4.39.0)(vite@6.3.4(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3)) + '@unocss/vite': 0.65.0-beta.2(rollup@4.39.0)(vite@6.3.4(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3)) optionalDependencies: - vite: 6.3.4(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.4(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - postcss - rollup - supports-color - vue - unocss@0.65.0-beta.2(postcss@8.5.6)(rollup@4.39.0)(vite@5.4.19(@types/node@22.15.21))(vue@3.5.13(typescript@5.8.3)): + unocss@0.65.0-beta.2(postcss@8.5.6)(rollup@4.39.0)(vite@5.4.19(@types/node@22.16.0))(vue@3.5.13(typescript@5.8.3)): dependencies: - '@unocss/astro': 0.65.0-beta.2(rollup@4.39.0)(vite@5.4.19(@types/node@22.15.21))(vue@3.5.13(typescript@5.8.3)) + '@unocss/astro': 0.65.0-beta.2(rollup@4.39.0)(vite@5.4.19(@types/node@22.16.0))(vue@3.5.13(typescript@5.8.3)) '@unocss/cli': 0.65.0-beta.2(rollup@4.39.0) '@unocss/core': 0.65.0-beta.2 '@unocss/postcss': 0.65.0-beta.2(postcss@8.5.6) @@ -16742,9 +17479,9 @@ snapshots: '@unocss/transformer-compile-class': 0.65.0-beta.2 '@unocss/transformer-directives': 0.65.0-beta.2 '@unocss/transformer-variant-group': 0.65.0-beta.2 - '@unocss/vite': 0.65.0-beta.2(rollup@4.39.0)(vite@5.4.19(@types/node@22.15.21))(vue@3.5.13(typescript@5.8.3)) + '@unocss/vite': 0.65.0-beta.2(rollup@4.39.0)(vite@5.4.19(@types/node@22.16.0))(vue@3.5.13(typescript@5.8.3)) optionalDependencies: - vite: 5.4.19(@types/node@22.15.21) + vite: 5.4.19(@types/node@22.16.0) transitivePeerDependencies: - postcss - rollup @@ -16758,28 +17495,6 @@ snapshots: - encoding - supports-color - unrs-resolver@1.7.2: - dependencies: - napi-postinstall: 0.2.4 - optionalDependencies: - '@unrs/resolver-binding-darwin-arm64': 1.7.2 - '@unrs/resolver-binding-darwin-x64': 1.7.2 - '@unrs/resolver-binding-freebsd-x64': 1.7.2 - '@unrs/resolver-binding-linux-arm-gnueabihf': 1.7.2 - '@unrs/resolver-binding-linux-arm-musleabihf': 1.7.2 - '@unrs/resolver-binding-linux-arm64-gnu': 1.7.2 - '@unrs/resolver-binding-linux-arm64-musl': 1.7.2 - '@unrs/resolver-binding-linux-ppc64-gnu': 1.7.2 - '@unrs/resolver-binding-linux-riscv64-gnu': 1.7.2 - '@unrs/resolver-binding-linux-riscv64-musl': 1.7.2 - '@unrs/resolver-binding-linux-s390x-gnu': 1.7.2 - '@unrs/resolver-binding-linux-x64-gnu': 1.7.2 - '@unrs/resolver-binding-linux-x64-musl': 1.7.2 - '@unrs/resolver-binding-wasm32-wasi': 1.7.2 - '@unrs/resolver-binding-win32-arm64-msvc': 1.7.2 - '@unrs/resolver-binding-win32-ia32-msvc': 1.7.2 - '@unrs/resolver-binding-win32-x64-msvc': 1.7.2 - unstorage@1.16.0(@azure/storage-blob@12.27.0)(idb-keyval@6.2.1): dependencies: anymatch: 3.1.3 @@ -16879,16 +17594,15 @@ snapshots: - supports-color - terser - vite-node@3.1.3(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0): + vite-node@3.2.4(@types/node@22.16.0): dependencies: cac: 6.7.14 debug: 4.4.1 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.3.5(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 5.4.19(@types/node@22.16.0) transitivePeerDependencies: - '@types/node' - - jiti - less - lightningcss - sass @@ -16897,11 +17611,26 @@ snapshots: - sugarss - supports-color - terser - - tsx - - yaml - optional: true - vite-plugin-solid@2.11.6(solid-js@1.9.7)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0)): + vite-node@3.2.4(@types/node@24.0.10): + dependencies: + cac: 6.7.14 + debug: 4.4.1 + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 5.4.19(@types/node@24.0.10) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite-plugin-solid@2.11.6(solid-js@1.9.7)(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0)): dependencies: '@babel/core': 7.26.0 '@types/babel__core': 7.20.5 @@ -16909,12 +17638,12 @@ snapshots: merge-anything: 5.1.7 solid-js: 1.9.7 solid-refresh: 0.6.3(solid-js@1.9.7) - vite: 6.3.5(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0) - vitefu: 1.0.6(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0)) + vite: 6.3.5(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0) + vitefu: 1.0.6(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0)) transitivePeerDependencies: - supports-color - vite-plugin-solid@2.11.7(solid-js@1.9.7)(vite@5.4.19(@types/node@22.15.21)): + vite-plugin-solid@2.11.7(solid-js@1.9.7)(vite@5.4.19(@types/node@22.16.0)): dependencies: '@babel/core': 7.26.0 '@types/babel__core': 7.20.5 @@ -16922,8 +17651,8 @@ snapshots: merge-anything: 5.1.7 solid-js: 1.9.7 solid-refresh: 0.6.3(solid-js@1.9.7) - vite: 5.4.19(@types/node@22.15.21) - vitefu: 1.0.6(vite@5.4.19(@types/node@22.15.21)) + vite: 5.4.19(@types/node@22.16.0) + vitefu: 1.0.6(vite@5.4.19(@types/node@22.16.0)) transitivePeerDependencies: - supports-color @@ -16936,7 +17665,25 @@ snapshots: '@types/node': 22.15.21 fsevents: 2.3.3 - vite@6.3.4(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0): + vite@5.4.19(@types/node@22.16.0): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.3 + rollup: 4.39.0 + optionalDependencies: + '@types/node': 22.16.0 + fsevents: 2.3.3 + + vite@5.4.19(@types/node@24.0.10): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.3 + rollup: 4.39.0 + optionalDependencies: + '@types/node': 24.0.10 + fsevents: 2.3.3 + + vite@6.3.4(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0): dependencies: esbuild: 0.25.2 fdir: 6.4.4(picomatch@4.0.2) @@ -16945,13 +17692,13 @@ snapshots: rollup: 4.39.0 tinyglobby: 0.2.14 optionalDependencies: - '@types/node': 22.15.21 + '@types/node': 24.0.10 fsevents: 2.3.3 jiti: 2.4.2 tsx: 4.20.3 yaml: 2.8.0 - vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0): + vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0): dependencies: esbuild: 0.25.2 fdir: 6.4.4(picomatch@4.0.2) @@ -16960,103 +17707,23 @@ snapshots: rollup: 4.39.0 tinyglobby: 0.2.14 optionalDependencies: - '@types/node': 22.15.21 + '@types/node': 24.0.10 fsevents: 2.3.3 jiti: 2.4.2 tsx: 4.20.3 yaml: 2.8.0 - vitefu@1.0.6(vite@5.4.19(@types/node@22.15.21)): + vitefu@1.0.6(vite@5.4.19(@types/node@22.16.0)): optionalDependencies: - vite: 5.4.19(@types/node@22.15.21) + vite: 5.4.19(@types/node@22.16.0) - vitefu@1.0.6(vite@6.3.4(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0)): + vitefu@1.0.6(vite@6.3.4(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0)): optionalDependencies: - vite: 6.3.4(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.4(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0) - vitefu@1.0.6(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0)): + vitefu@1.0.6(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0)): optionalDependencies: - vite: 6.3.5(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0) - - vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jiti@2.4.2)(jsdom@26.0.0)(tsx@4.20.3)(yaml@2.8.0): - dependencies: - '@vitest/expect': 3.1.3 - '@vitest/mocker': 3.1.3(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0)) - '@vitest/pretty-format': 3.1.3 - '@vitest/runner': 3.1.3 - '@vitest/snapshot': 3.1.3 - '@vitest/spy': 3.1.3 - '@vitest/utils': 3.1.3 - chai: 5.2.0 - debug: 4.4.1 - expect-type: 1.2.1 - magic-string: 0.30.17 - pathe: 2.0.3 - std-env: 3.9.0 - tinybench: 2.9.0 - tinyexec: 0.3.2 - tinyglobby: 0.2.14 - tinypool: 1.0.2 - tinyrainbow: 2.0.0 - vite: 6.3.5(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0) - vite-node: 3.1.3(@types/node@22.15.21)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/debug': 4.1.12 - '@types/node': 22.15.21 - jsdom: 26.0.0 - transitivePeerDependencies: - - jiti - - less - - lightningcss - - msw - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - optional: true - - vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@25.0.1(canvas@2.11.2)): - dependencies: - '@vitest/expect': 3.1.3 - '@vitest/mocker': 3.1.3(vite@5.4.19(@types/node@22.15.21)) - '@vitest/pretty-format': 3.1.3 - '@vitest/runner': 3.1.3 - '@vitest/snapshot': 3.1.3 - '@vitest/spy': 3.1.3 - '@vitest/utils': 3.1.3 - chai: 5.2.0 - debug: 4.4.1 - expect-type: 1.2.1 - magic-string: 0.30.17 - pathe: 2.0.3 - std-env: 3.9.0 - tinybench: 2.9.0 - tinyexec: 0.3.2 - tinyglobby: 0.2.14 - tinypool: 1.0.2 - tinyrainbow: 2.0.0 - vite: 5.4.19(@types/node@22.15.21) - vite-node: 3.1.3(@types/node@22.15.21) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/debug': 4.1.12 - '@types/node': 22.15.21 - jsdom: 25.0.1(canvas@2.11.2) - transitivePeerDependencies: - - less - - lightningcss - - msw - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser + vite: 6.3.5(@types/node@24.0.10)(jiti@2.4.2)(tsx@4.20.3)(yaml@2.8.0) vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.21)(jsdom@26.0.0): dependencies: @@ -17096,15 +17763,134 @@ snapshots: - supports-color - terser - vue-eslint-parser@10.1.3(eslint@9.27.0(jiti@2.4.2)): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(jsdom@25.0.1(canvas@2.11.2)): + dependencies: + '@types/chai': 5.2.2 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(vite@5.4.19(@types/node@22.16.0)) + '@vitest/pretty-format': 3.2.4 + '@vitest/runner': 3.2.4 + '@vitest/snapshot': 3.2.4 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.2.0 + debug: 4.4.1 + expect-type: 1.2.1 + magic-string: 0.30.17 + pathe: 2.0.3 + picomatch: 4.0.2 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.14 + tinypool: 1.1.1 + tinyrainbow: 2.0.0 + vite: 5.4.19(@types/node@22.16.0) + vite-node: 3.2.4(@types/node@22.16.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/debug': 4.1.12 + '@types/node': 22.16.0 + jsdom: 25.0.1(canvas@2.11.2) + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(jsdom@26.0.0): + dependencies: + '@types/chai': 5.2.2 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(vite@5.4.19(@types/node@22.16.0)) + '@vitest/pretty-format': 3.2.4 + '@vitest/runner': 3.2.4 + '@vitest/snapshot': 3.2.4 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.2.0 + debug: 4.4.1 + expect-type: 1.2.1 + magic-string: 0.30.17 + pathe: 2.0.3 + picomatch: 4.0.2 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.14 + tinypool: 1.1.1 + tinyrainbow: 2.0.0 + vite: 5.4.19(@types/node@22.16.0) + vite-node: 3.2.4(@types/node@22.16.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/debug': 4.1.12 + '@types/node': 22.16.0 + jsdom: 26.0.0 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.0.10)(jsdom@26.0.0): + dependencies: + '@types/chai': 5.2.2 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(vite@5.4.19(@types/node@24.0.10)) + '@vitest/pretty-format': 3.2.4 + '@vitest/runner': 3.2.4 + '@vitest/snapshot': 3.2.4 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.2.0 + debug: 4.4.1 + expect-type: 1.2.1 + magic-string: 0.30.17 + pathe: 2.0.3 + picomatch: 4.0.2 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.14 + tinypool: 1.1.1 + tinyrainbow: 2.0.0 + vite: 5.4.19(@types/node@24.0.10) + vite-node: 3.2.4(@types/node@24.0.10) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/debug': 4.1.12 + '@types/node': 24.0.10 + jsdom: 26.0.0 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vue-eslint-parser@10.2.0(eslint@9.30.1(jiti@2.4.2)): dependencies: debug: 4.4.1 - eslint: 9.27.0(jiti@2.4.2) - eslint-scope: 8.3.0 - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 + eslint: 9.30.1(jiti@2.4.2) + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 esquery: 1.6.0 - lodash: 4.17.21 semver: 7.7.2 transitivePeerDependencies: - supports-color @@ -17220,6 +18006,9 @@ snapshots: ws@8.18.2: {} + ws@8.18.3: + optional: true + xml-name-validator@4.0.0: {} xml-name-validator@5.0.0: {} @@ -17283,6 +18072,8 @@ snapshots: zod@3.25.67: {} + zod@3.25.73: {} + zustand@5.0.3(react@18.3.1)(use-sync-external-store@1.2.2(react@18.3.1)): optionalDependencies: react: 18.3.1 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 17715e3..7290895 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -3,9 +3,9 @@ packages: - apps/* catalog: - '@antfu/eslint-config': ^4.12.0 + '@antfu/eslint-config': ^4.16.2 '@types/node': ^22.15.21 - eslint: ^9.25.1 + eslint: ^9.30.1 tsx: ^4.17.0 typescript: ^5.6.2 vitest: ^3.0.5