From e27b45ec49217807d5bedb28f34c5294423c3832 Mon Sep 17 00:00:00 2001 From: Innei Date: Fri, 31 Oct 2025 21:49:31 +0800 Subject: [PATCH] feat(builder): upload thumbnails via storage plugin (#137) Signed-off-by: Innei Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> --- AGENTS.md | 1 + apps/ssr/package.json | 8 +- apps/web/package.json | 18 +- apps/web/src/styles/tailwind.css | 30 - be/apps/core/package.json | 15 +- .../core/src/modules/auth/auth.provider.ts | 23 + .../modules/dashboard/dashboard.controller.ts | 15 + .../src/modules/dashboard/dashboard.module.ts | 12 + .../modules/dashboard/dashboard.service.ts | 96 + .../src/modules/dashboard/dashboard.types.ts | 34 + .../src/modules/data-sync/data-sync.dto.ts | 40 +- .../modules/data-sync/data-sync.service.ts | 1 + be/apps/core/src/modules/index.module.ts | 4 + .../src/modules/photo/photo-asset.service.ts | 158 +- .../modules/photo/photo-storage.service.ts | 99 +- .../src/modules/photo/photo.controller.ts | 2 - .../core/src/modules/photo/photo.service.ts | 31 +- .../modules/reaction/reaction.controller.ts | 50 + .../core/src/modules/reaction/reaction.dto.ts | 8 + .../src/modules/reaction/reaction.module.ts | 10 + .../src/modules/reaction/reaction.service.ts | 78 + .../modules/setting/storage-provider.utils.ts | 2 +- .../super-admin-setting.service.ts | 21 + .../super-admin-setting.ui-schema.ts | 4 - be/apps/core/vite.config.ts | 46 +- be/apps/dashboard/package.json | 12 +- .../plugins/eslint-recursive-sort.js | 2 +- be/apps/dashboard/src/App.tsx | 4 +- be/apps/dashboard/src/atoms/auth.ts | 8 +- be/apps/dashboard/src/atoms/context-menu.ts | 8 +- be/apps/dashboard/src/atoms/route.ts | 2 +- .../src/components/common/GlassPanel.tsx | 16 + .../src/components/common/NotFound.tsx | 2 +- .../src/components/layouts/MainPageLayout.tsx | 6 +- .../src/components/navigation/PageTabs.tsx | 2 +- be/apps/dashboard/src/hooks/useBlock.ts | 4 +- .../dashboard/src/hooks/usePageRedirect.ts | 2 +- be/apps/dashboard/src/lib/case.ts | 6 +- be/apps/dashboard/src/lib/dev.tsx | 4 +- be/apps/dashboard/src/lib/dom.ts | 4 +- be/apps/dashboard/src/lib/jotai.ts | 12 +- be/apps/dashboard/src/lib/ns.ts | 2 +- .../dashboard/src/modules/auth/api/login.ts | 2 +- .../dashboard/src/modules/auth/api/session.ts | 5 +- .../src/modules/auth/hooks/useLogin.ts | 2 +- .../dashboard/src/modules/dashboard/api.ts | 14 + .../components/DashboardOverview.tsx | 376 +++ .../dashboard/src/modules/dashboard/hooks.ts | 14 + .../dashboard/src/modules/dashboard/types.ts | 30 + .../dashboard/src/modules/onboarding/api.ts | 10 +- .../components/steps/TenantStep.tsx | 2 +- .../onboarding/hooks/useOnboardingWizard.ts | 2 +- .../dashboard/src/modules/onboarding/utils.ts | 11 +- be/apps/dashboard/src/modules/photos/api.ts | 22 +- .../modules/photos/components/PhotoPage.tsx | 7 +- .../photos/components/library/Masonry.tsx | 2 +- .../library/PhotoLibraryActionBar.tsx | 4 +- .../components/library/PhotoLibraryGrid.tsx | 8 +- .../components/sync/PhotoSyncActions.tsx | 2 +- .../sync/PhotoSyncConflictsPanel.tsx | 46 +- .../sync/PhotoSyncProgressPanel.tsx | 4 +- .../components/sync/PhotoSyncResultPanel.tsx | 30 +- .../dashboard/src/modules/photos/constants.ts | 2 +- be/apps/dashboard/src/modules/photos/hooks.ts | 12 +- .../schema-form/SchemaFormRenderer.tsx | 53 +- .../src/modules/schema-form/types.ts | 2 +- .../src/modules/schema-form/utils.ts | 4 +- be/apps/dashboard/src/modules/settings/api.ts | 8 +- .../settings/components/SettingsForm.tsx | 17 +- .../components/SettingsNavigation.tsx | 2 +- .../dashboard/src/modules/settings/hooks.ts | 6 +- .../components/ProviderEditModal.tsx | 4 +- .../components/StorageProvidersManager.tsx | 2 +- .../modules/storage-providers/constants.ts | 2 +- .../src/modules/storage-providers/hooks.ts | 8 +- .../src/modules/storage-providers/utils.ts | 29 +- .../dashboard/src/modules/super-admin/api.ts | 7 +- .../components/SuperAdminSettingsForm.tsx | 44 +- .../src/modules/super-admin/hooks.ts | 7 +- .../dashboard/src/pages/(main)/analytics.tsx | 2 +- be/apps/dashboard/src/pages/(main)/index.tsx | 69 +- be/apps/dashboard/src/pages/(main)/layout.tsx | 2 +- be/apps/dashboard/src/pages/(main)/photos.tsx | 2 +- .../src/pages/(main)/settings/index.tsx | 2 +- .../src/pages/(main)/settings/storage.tsx | 2 +- .../src/pages/(onboarding)/login.tsx | 2 +- .../dashboard/src/pages/superadmin/index.tsx | 2 +- .../dashboard/src/pages/superadmin/layout.tsx | 2 +- .../src/pages/superadmin/settings.tsx | 2 +- .../src/providers/context-menu-provider.tsx | 2 +- .../src/providers/stable-router-provider.tsx | 2 +- .../migrations/0003_lovely_wendell_rand.sql | 9 + .../db/migrations/meta/0003_snapshot.json | 834 ++++++ be/packages/db/migrations/meta/_journal.json | 7 + be/packages/db/package.json | 2 +- be/packages/db/src/schema.ts | 20 +- be/packages/framework/package.json | 8 +- be/packages/task-queue/package.json | 6 +- be/packages/utils/package.json | 2 +- builder.config.default.ts | 4 +- package.json | 2 +- packages/builder/package.json | 10 +- packages/builder/src/builder/builder.ts | 6 +- packages/builder/src/config/defaults.ts | 3 +- packages/builder/src/config/helper.ts | 5 + packages/builder/src/config/index.ts | 4 - packages/builder/src/index.ts | 4 +- packages/builder/src/photo/image-pipeline.ts | 8 + .../src/plugins/thumbnail-storage/index.ts | 190 ++ .../src/plugins/thumbnail-storage/shared.ts | 18 + packages/builder/src/storage/manager.ts | 38 +- packages/docs/package.json | 8 +- packages/ui/package.json | 2 +- packages/ui/src/sonner.tsx | 1 - packages/webgl-viewer/package.json | 4 +- pnpm-lock.yaml | 2312 ++++++++--------- 116 files changed, 3541 insertions(+), 1761 deletions(-) create mode 100644 be/apps/core/src/modules/dashboard/dashboard.controller.ts create mode 100644 be/apps/core/src/modules/dashboard/dashboard.module.ts create mode 100644 be/apps/core/src/modules/dashboard/dashboard.service.ts create mode 100644 be/apps/core/src/modules/dashboard/dashboard.types.ts create mode 100644 be/apps/core/src/modules/reaction/reaction.controller.ts create mode 100644 be/apps/core/src/modules/reaction/reaction.dto.ts create mode 100644 be/apps/core/src/modules/reaction/reaction.module.ts create mode 100644 be/apps/core/src/modules/reaction/reaction.service.ts create mode 100644 be/apps/dashboard/src/components/common/GlassPanel.tsx create mode 100644 be/apps/dashboard/src/modules/dashboard/api.ts create mode 100644 be/apps/dashboard/src/modules/dashboard/components/DashboardOverview.tsx create mode 100644 be/apps/dashboard/src/modules/dashboard/hooks.ts create mode 100644 be/apps/dashboard/src/modules/dashboard/types.ts create mode 100644 be/packages/db/migrations/0003_lovely_wendell_rand.sql create mode 100644 be/packages/db/migrations/meta/0003_snapshot.json create mode 100644 packages/builder/src/config/helper.ts create mode 100644 packages/builder/src/plugins/thumbnail-storage/index.ts create mode 100644 packages/builder/src/plugins/thumbnail-storage/shared.ts diff --git a/AGENTS.md b/AGENTS.md index b4cfc103..d2657e5e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -163,6 +163,7 @@ class PhotoLoader { - **Hot Reloading**: SPA changes reflect immediately, SSR provides SEO preview - **Manifest Building**: `pnpm run build:manifest` processes photos and updates data - **Type Safety**: Shared types between builder, SPA, and SSR ensure consistency +- **Page Structure**: Keep files under `pages/` as thin routing shells; move reusable UI/logic into `modules//**` (e.g., dashboard overview lives in `modules/dashboard/components`). ### Code Quality Rules diff --git a/apps/ssr/package.json b/apps/ssr/package.json index 0806e6d6..71b21e15 100644 --- a/apps/ssr/package.json +++ b/apps/ssr/package.json @@ -43,15 +43,15 @@ "@iconify-json/mingcute": "catalog:", "@tailwindcss/postcss": "catalog:", "@tailwindcss/typography": "catalog:", - "@types/node": "24.9.1", - "@types/pg": "8.15.5", + "@types/node": "24.9.2", + "@types/pg": "8.15.6", "@types/react": "19.2.2", "@types/react-dom": "19.2.2", "concurrently": "9.2.1", "cross-env": "10.1.0", "dotenv-expand": "catalog:", - "drizzle-kit": "0.31.5", - "next": "16.0.0", + "drizzle-kit": "0.31.6", + "next": "16.0.1", "postcss": "8.5.6", "tailwind-scrollbar": "catalog:", "tailwindcss": "catalog:", diff --git a/apps/web/package.json b/apps/web/package.json index 14d385e0..89747091 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -35,7 +35,7 @@ "@t3-oss/env-core": "catalog:", "@tanstack/react-query": "5.90.5", "@use-gesture/react": "10.3.1", - "@uswriting/exiftool": "1.0.3", + "@uswriting/exiftool": "1.0.5", "blurhash": "2.0.5", "clsx": "2.1.1", "consola": "3.4.2", @@ -46,23 +46,23 @@ "heic-to": "1.3.0", "i18next": "25.6.0", "i18next-browser-languagedetector": "8.2.0", - "immer": "10.1.3", + "immer": "10.2.0", "jotai": "2.15.0", - "maplibre-gl": "^5.9.0", + "maplibre-gl": "^5.10.0", "masonic": "4.1.0", "motion": "12.23.24", - "ofetch": "1.4.1", + "ofetch": "1.5.0", "react": "19.2.0", "react-blurhash": "0.3.0", "react-dom": "19.2.0", "react-error-boundary": "6.0.0", "react-freeze": "1.0.4", - "react-i18next": "16.2.0", + "react-i18next": "16.2.3", "react-image-gallery": "1.4.0", - "react-intersection-observer": "9.16.0", + "react-intersection-observer": "10.0.0", "react-map-gl": "^8.1.0", "react-remove-scroll": "2.7.1", - "react-router": "7.9.4", + "react-router": "7.9.5", "react-scan": "0.4.3", "react-use-measure": "2.1.7", "react-zoom-pan-pinch": "3.7.0", @@ -85,14 +85,14 @@ "@tailwindcss/postcss": "catalog:", "@tailwindcss/typography": "catalog:", "@tailwindcss/vite": "4.1.16", - "@types/node": "24.9.1", + "@types/node": "24.9.2", "@types/react": "19.2.2", "@types/react-dom": "19.2.2", "@vitejs/plugin-react": "^5.1.0", "ast-kit": "2.1.3", "babel-plugin-react-compiler": "19.1.0-rc.3", "code-inspector-plugin": "1.2.10", - "daisyui": "5.3.9", + "daisyui": "5.3.10", "execa": "9.6.0", "kolorist": "1.8.0", "postcss": "8.5.6", diff --git a/apps/web/src/styles/tailwind.css b/apps/web/src/styles/tailwind.css index d4f49520..d77c78c5 100644 --- a/apps/web/src/styles/tailwind.css +++ b/apps/web/src/styles/tailwind.css @@ -142,11 +142,6 @@ html body { } [data-sonner-toast] { - background-image: linear-gradient( - to bottom right, - color-mix(in srgb, var(--color-background) 98%, transparent), - color-mix(in srgb, var(--color-background) 95%, transparent) - ) !important; border-color: color-mix(in srgb, var(--color-accent) 20%, transparent) !important; box-shadow: 0 8px 32px color-mix(in srgb, var(--color-accent) 8%, transparent), @@ -156,47 +151,22 @@ html body { [data-sonner-toast][data-type='success'] { border-color: rgba(48, 209, 88, 0.3) !important; - background-image: linear-gradient( - to bottom right, - rgba(48, 209, 88, 0.15), - color-mix(in srgb, var(--color-background) 95%, transparent) - ) !important; } [data-sonner-toast][data-type='error'] { border-color: rgba(255, 69, 58, 0.3) !important; - background-image: linear-gradient( - to bottom right, - rgba(255, 69, 58, 0.15), - color-mix(in srgb, var(--color-background) 95%, transparent) - ) !important; } [data-sonner-toast][data-type='warning'] { border-color: rgba(255, 159, 10, 0.3) !important; - background-image: linear-gradient( - to bottom right, - rgba(255, 159, 10, 0.15), - color-mix(in srgb, var(--color-background) 95%, transparent) - ) !important; } [data-sonner-toast][data-type='info'] { border-color: rgba(10, 132, 255, 0.3) !important; - background-image: linear-gradient( - to bottom right, - rgba(10, 132, 255, 0.15), - color-mix(in srgb, var(--color-background) 95%, transparent) - ) !important; } [data-sonner-toast][data-type='loading'] { border-color: rgba(142, 142, 147, 0.3) !important; - background-image: linear-gradient( - to bottom right, - rgba(142, 142, 147, 0.15), - color-mix(in srgb, var(--color-background) 95%, transparent) - ) !important; } [data-sonner-toast]::before { diff --git a/be/apps/core/package.json b/be/apps/core/package.json index f456b54e..c00fca29 100644 --- a/be/apps/core/package.json +++ b/be/apps/core/package.json @@ -23,11 +23,11 @@ "@afilmory/redis": "workspace:*", "@afilmory/task-queue": "workspace:*", "@afilmory/utils": "workspace:*", - "@aws-sdk/client-s3": "3.916.0", - "@hono/node-server": "^1.19.5", - "better-auth": "1.3.29", + "@aws-sdk/client-s3": "3.921.0", + "@hono/node-server": "^1.19.6", + "better-auth": "1.3.34", "drizzle-orm": "^0.44.7", - "hono": "4.10.2", + "hono": "4.10.4", "pg": "^8.16.3", "picocolors": "1.1.1", "reflect-metadata": "0.2.2", @@ -35,13 +35,14 @@ "zod": "^4.1.11" }, "devDependencies": { - "@types/node": "^24.9.1", - "@types/pg": "8.15.5", + "@types/node": "^24.9.2", + "@types/pg": "8.15.6", "nodemon": "3.1.10", "unplugin-swc": "1.5.8", "vite": "7.1.12", + "vite-bundle-analyzer": "1.2.3", "vite-node": "3.2.4", "vite-tsconfig-paths": "5.1.4", - "vitest": "4.0.3" + "vitest": "4.0.6" } } diff --git a/be/apps/core/src/modules/auth/auth.provider.ts b/be/apps/core/src/modules/auth/auth.provider.ts index 3806dd13..3ecff15d 100644 --- a/be/apps/core/src/modules/auth/auth.provider.ts +++ b/be/apps/core/src/modules/auth/auth.provider.ts @@ -3,11 +3,14 @@ import type { OnModuleInit } from '@afilmory/framework' import { createLogger, HttpContext } from '@afilmory/framework' import { betterAuth } from 'better-auth' import { drizzleAdapter } from 'better-auth/adapters/drizzle' +import { APIError, createAuthMiddleware } from 'better-auth/api' import { admin } from 'better-auth/plugins' +import { BizException } from 'core/errors' import type { Context } from 'hono' import { injectable } from 'tsyringe' import { DrizzleProvider } from '../../database/database.provider' +import { SuperAdminSettingService } from '../system-setting/super-admin-setting.service' import { AuthConfig } from './auth.config' export type BetterAuthInstance = ReturnType @@ -21,6 +24,7 @@ export class AuthProvider implements OnModuleInit { constructor( private readonly config: AuthConfig, private readonly drizzleProvider: DrizzleProvider, + private readonly superAdminSettings: SuperAdminSettingService, ) {} onModuleInit(): void { @@ -76,6 +80,25 @@ export class AuthProvider implements OnModuleInit { defaultBanReason: 'Spamming', }), ], + hooks: { + before: createAuthMiddleware(async (ctx) => { + if (ctx.path !== '/sign-up/email') { + return + } + + try { + await this.superAdminSettings.ensureRegistrationAllowed() + } catch (error) { + if (error instanceof BizException) { + throw new APIError('FORBIDDEN', { + message: error.message, + }) + } + + throw error + } + }), + }, }) } getAuth() { diff --git a/be/apps/core/src/modules/dashboard/dashboard.controller.ts b/be/apps/core/src/modules/dashboard/dashboard.controller.ts new file mode 100644 index 00000000..8ab76930 --- /dev/null +++ b/be/apps/core/src/modules/dashboard/dashboard.controller.ts @@ -0,0 +1,15 @@ +import { Controller, Get } from '@afilmory/framework' +import { Roles } from 'core/guards/roles.decorator' + +import { DashboardService } from './dashboard.service' + +@Controller('dashboard') +@Roles('admin') +export class DashboardController { + constructor(private readonly dashboardService: DashboardService) {} + + @Get('overview') + async getOverview() { + return await this.dashboardService.getOverview() + } +} diff --git a/be/apps/core/src/modules/dashboard/dashboard.module.ts b/be/apps/core/src/modules/dashboard/dashboard.module.ts new file mode 100644 index 00000000..b1548f62 --- /dev/null +++ b/be/apps/core/src/modules/dashboard/dashboard.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@afilmory/framework' + +import { DatabaseModule } from '../../database/database.module' +import { DashboardController } from './dashboard.controller' +import { DashboardService } from './dashboard.service' + +@Module({ + imports: [DatabaseModule], + controllers: [DashboardController], + providers: [DashboardService], +}) +export class DashboardModule {} diff --git a/be/apps/core/src/modules/dashboard/dashboard.service.ts b/be/apps/core/src/modules/dashboard/dashboard.service.ts new file mode 100644 index 00000000..2d39d884 --- /dev/null +++ b/be/apps/core/src/modules/dashboard/dashboard.service.ts @@ -0,0 +1,96 @@ +import { photoAssets } from '@afilmory/db' +import { desc, eq, sql } from 'drizzle-orm' +import { injectable } from 'tsyringe' + +import { DbAccessor } from '../../database/database.provider' +import { requireTenantContext } from '../tenant/tenant.context' +import type { DashboardOverview, DashboardRecentActivityItem } from './dashboard.types' + +const ZERO_STATS = { + totalPhotos: 0, + totalStorageBytes: 0, + thisMonthUploads: 0, + previousMonthUploads: 0, + sync: { + synced: 0, + pending: 0, + conflicts: 0, + }, +} as const + +@injectable() +export class DashboardService { + constructor(private readonly dbAccessor: DbAccessor) {} + + async getOverview(): Promise { + const tenant = requireTenantContext() + const db = this.dbAccessor.get() + + const [rawStats] = await db + .select({ + totalPhotos: sql`count(*)`, + totalStorageBytes: sql`coalesce(sum(${photoAssets.size}), 0)`, + thisMonthUploads: sql`count(*) filter (where date_trunc('month', ${photoAssets.createdAt}) = date_trunc('month', now()))`, + previousMonthUploads: sql`count(*) filter (where date_trunc('month', ${photoAssets.createdAt}) = date_trunc('month', now() - interval '1 month'))`, + synced: sql`count(*) filter (where ${photoAssets.syncStatus} = 'synced')`, + pending: sql`count(*) filter (where ${photoAssets.syncStatus} = 'pending')`, + conflicts: sql`count(*) filter (where ${photoAssets.syncStatus} = 'conflict')`, + }) + .from(photoAssets) + .where(eq(photoAssets.tenantId, tenant.tenant.id)) + + const stats = rawStats + ? { + totalPhotos: Number(rawStats.totalPhotos ?? 0), + totalStorageBytes: Number(rawStats.totalStorageBytes ?? 0), + thisMonthUploads: Number(rawStats.thisMonthUploads ?? 0), + previousMonthUploads: Number(rawStats.previousMonthUploads ?? 0), + sync: { + synced: Number(rawStats.synced ?? 0), + pending: Number(rawStats.pending ?? 0), + conflicts: Number(rawStats.conflicts ?? 0), + }, + } + : { ...ZERO_STATS } + + const recentRecords = await db + .select({ + id: photoAssets.id, + photoId: photoAssets.photoId, + createdAt: photoAssets.createdAt, + storageProvider: photoAssets.storageProvider, + manifest: photoAssets.manifest, + size: photoAssets.size, + syncStatus: photoAssets.syncStatus, + }) + .from(photoAssets) + .where(eq(photoAssets.tenantId, tenant.tenant.id)) + .orderBy(desc(photoAssets.createdAt)) + .limit(8) + + const recentActivity: DashboardRecentActivityItem[] = recentRecords.map((record) => { + const { manifest } = record + const manifestData = manifest?.data + const tags = manifestData?.tags?.slice(0, 5) ?? [] + + return { + id: record.id, + photoId: record.photoId, + title: manifestData?.title?.trim() || manifestData?.description?.trim() || record.photoId, + description: manifestData?.description?.trim() || null, + createdAt: record.createdAt, + takenAt: manifestData?.dateTaken ?? null, + storageProvider: record.storageProvider, + size: record.size ?? null, + syncStatus: record.syncStatus, + tags, + previewUrl: manifestData?.thumbnailUrl ?? manifestData?.originalUrl ?? null, + } + }) + + return { + stats, + recentActivity, + } + } +} diff --git a/be/apps/core/src/modules/dashboard/dashboard.types.ts b/be/apps/core/src/modules/dashboard/dashboard.types.ts new file mode 100644 index 00000000..80051448 --- /dev/null +++ b/be/apps/core/src/modules/dashboard/dashboard.types.ts @@ -0,0 +1,34 @@ +import type { photoAssets } from '@afilmory/db' + +type PhotoAssetSyncStatus = (typeof photoAssets.$inferSelect)['syncStatus'] + +export interface DashboardStats { + totalPhotos: number + totalStorageBytes: number + thisMonthUploads: number + previousMonthUploads: number + sync: { + synced: number + pending: number + conflicts: number + } +} + +export interface DashboardRecentActivityItem { + id: string + photoId: string + title: string + description: string | null + createdAt: string + takenAt: string | null + storageProvider: string + size: number | null + syncStatus: PhotoAssetSyncStatus + tags: string[] + previewUrl: string | null +} + +export interface DashboardOverview { + stats: DashboardStats + recentActivity: DashboardRecentActivityItem[] +} diff --git a/be/apps/core/src/modules/data-sync/data-sync.dto.ts b/be/apps/core/src/modules/data-sync/data-sync.dto.ts index 936ca9e2..c313801f 100644 --- a/be/apps/core/src/modules/data-sync/data-sync.dto.ts +++ b/be/apps/core/src/modules/data-sync/data-sync.dto.ts @@ -36,45 +36,7 @@ const githubConfigSchema = z.object({ useRawUrl: z.boolean().optional(), }) -const localConfigSchema = z.object({ - provider: z.literal('local'), - basePath: z.string().min(1), - baseUrl: z.string().optional(), - distPath: z.string().optional(), - excludeRegex: z.string().optional(), - maxFileLimit: z.number().int().positive().optional(), -}) - -const eagleRuleSchema = z.union([ - z.object({ - type: z.literal('tag'), - name: z.string().min(1), - }), - z.object({ - type: z.literal('folder'), - name: z.string().min(1), - includeSubfolder: z.boolean().optional(), - }), - z.object({ - type: z.literal('smartFolder'), - }), -]) - -const eagleConfigSchema = z.object({ - provider: z.literal('eagle'), - libraryPath: z.string().min(1), - distPath: z.string().optional(), - baseUrl: z.string().optional(), - include: z.array(eagleRuleSchema).optional(), - exclude: z.array(eagleRuleSchema).optional(), -}) - -const storageConfigSchema = z.discriminatedUnion('provider', [ - s3ConfigSchema, - githubConfigSchema, - localConfigSchema, - eagleConfigSchema, -]) +const storageConfigSchema = z.discriminatedUnion('provider', [s3ConfigSchema, githubConfigSchema]) const builderConfigSchema = z .object({ diff --git a/be/apps/core/src/modules/data-sync/data-sync.service.ts b/be/apps/core/src/modules/data-sync/data-sync.service.ts index f92de226..1b6a6a52 100644 --- a/be/apps/core/src/modules/data-sync/data-sync.service.ts +++ b/be/apps/core/src/modules/data-sync/data-sync.service.ts @@ -1263,6 +1263,7 @@ export class DataSyncService { this.photoBuilderService.applyStorageConfig(builder, options.storageConfig) } + this.photoStorageService.registerStorageProviderPlugin(builder, effectiveStorageConfig) const storageManager = builder.getStorageManager() if (payload.type === 'missing-in-storage') { diff --git a/be/apps/core/src/modules/index.module.ts b/be/apps/core/src/modules/index.module.ts index 6ed417b5..d661089c 100644 --- a/be/apps/core/src/modules/index.module.ts +++ b/be/apps/core/src/modules/index.module.ts @@ -8,9 +8,11 @@ import { RedisAccessor } from 'core/redis/redis.provider' import { DatabaseModule } from '../database/database.module' import { RedisModule } from '../redis/redis.module' import { AuthModule } from './auth/auth.module' +import { DashboardModule } from './dashboard/dashboard.module' import { DataSyncModule } from './data-sync/data-sync.module' import { OnboardingModule } from './onboarding/onboarding.module' import { PhotoModule } from './photo/photo.module' +import { ReactionModule } from './reaction/reaction.module' import { SettingModule } from './setting/setting.module' import { SuperAdminModule } from './super-admin/super-admin.module' import { SystemSettingModule } from './system-setting/system-setting.module' @@ -32,6 +34,8 @@ function createEventModuleOptions(redis: RedisAccessor) { SuperAdminModule, OnboardingModule, PhotoModule, + ReactionModule, + DashboardModule, TenantModule, DataSyncModule, EventModule.forRootAsync({ diff --git a/be/apps/core/src/modules/photo/photo-asset.service.ts b/be/apps/core/src/modules/photo/photo-asset.service.ts index 9d71b18c..e2157b69 100644 --- a/be/apps/core/src/modules/photo/photo-asset.service.ts +++ b/be/apps/core/src/modules/photo/photo-asset.service.ts @@ -1,6 +1,10 @@ import path from 'node:path' import type { BuilderConfig, PhotoManifestItem, StorageConfig, StorageObject } from '@afilmory/builder' +import { + DEFAULT_CONTENT_TYPE, + DEFAULT_DIRECTORY as DEFAULT_THUMBNAIL_DIRECTORY, +} from '@afilmory/builder/plugins/thumbnail-storage/shared.js' import { StorageManager } from '@afilmory/builder/storage/index.js' import type { PhotoAssetManifest } from '@afilmory/db' import { CURRENT_PHOTO_MANIFEST_VERSION, DATABASE_ONLY_PROVIDER, photoAssets } from '@afilmory/db' @@ -15,6 +19,9 @@ import { PhotoStorageService } from './photo-storage.service' type PhotoAssetRecord = typeof photoAssets.$inferSelect +const DEFAULT_THUMBNAIL_EXTENSION = { + 'image/jpeg': '.jpg', +}[DEFAULT_CONTENT_TYPE] export interface PhotoAssetListItem { id: string photoId: string @@ -40,9 +47,9 @@ export interface UploadAssetInput { filename: string buffer: Buffer contentType?: string - directory?: string | null } + @injectable() export class PhotoAssetService { constructor( @@ -140,6 +147,8 @@ export class PhotoAssetService { const { builderConfig, storageConfig } = await this.photoStorageService.resolveConfigForTenant(tenant.tenant.id) const storageManager = this.createStorageManager(builderConfig, storageConfig) + const thumbnailRemotePrefix = this.resolveThumbnailRemotePrefix(storageConfig) + const deletedThumbnailKeys = new Set() for (const record of records) { if (record.storageProvider !== DATABASE_ONLY_PROVIDER) { @@ -150,6 +159,18 @@ export class PhotoAssetService { message: `无法删除存储中的文件 ${record.storageKey}: ${String(error)}`, }) } + + const thumbnailKey = this.resolveThumbnailStorageKey(record, thumbnailRemotePrefix) + if (thumbnailKey && !deletedThumbnailKeys.has(thumbnailKey)) { + try { + await storageManager.deleteFile(thumbnailKey) + deletedThumbnailKeys.add(thumbnailKey) + } catch (error) { + throw new BizException(ErrorCode.IMAGE_PROCESSING_FAILED, { + message: `无法删除缩略图文件 ${thumbnailKey}: ${String(error)}`, + }) + } + } } } @@ -173,7 +194,7 @@ export class PhotoAssetService { const results: PhotoAssetListItem[] = [] for (const input of inputs) { - const key = this.createStorageKey(input) + const key = this.createStorageKey(input, storageConfig) const storageObject = await storageManager.uploadFile(key, input.buffer, { contentType: input.contentType, }) @@ -197,7 +218,7 @@ export class PhotoAssetService { const manifest = this.createManifestPayload(item) const snapshot = this.createStorageSnapshot(storageObject) - const now = this.nowIso() + const now = new Date().toISOString() const insertPayload: typeof photoAssets.$inferInsert = { tenantId: tenant.tenant.id, @@ -316,19 +337,126 @@ export class PhotoAssetService { } } - private nowIso(): string { - return new Date().toISOString() + private createStorageKey(input: UploadAssetInput, storageConfig: StorageConfig): string { + const ext = path.extname(input.filename) + const base = path.basename(input.filename, ext).trim() + + const timestamp = Date.now().toString() + const directory = this.resolveStorageDirectory(storageConfig) + const keySegment = base || timestamp + const normalized = directory ? `${directory}/${keySegment}${ext}` : `${keySegment}${ext}` + return this.normalizeKeyPath(normalized) } - private createStorageKey(input: UploadAssetInput): string { - const ext = path.extname(input.filename) - const base = path.basename(input.filename, ext) - const slug = base - .toLowerCase() - .replaceAll(/[^a-z0-9]+/g, '-') - .replaceAll(/^-+|-+$/g, '') - const timestamp = Date.now() - const dir = input.directory?.trim() ? input.directory.trim().replaceAll(/\\+/g, '/') : 'uploads' - return `${dir}/${timestamp}-${slug || 'photo'}${ext}`.replaceAll(/\\+/g, '/') + private resolveStorageDirectory(storageConfig: StorageConfig): string | null { + switch (storageConfig.provider) { + case 's3': { + return this.normalizeDirectory(storageConfig.prefix) + } + case 'github': { + return this.normalizeDirectory(storageConfig.path) + } + default: { + return null + } + } + } + + private normalizeDirectory(value?: string | null): string | null { + if (!value) { + return null + } + const trimmed = value.trim() + if (trimmed.length === 0) { + return null + } + const normalized = this.normalizeKeyPath(trimmed) + return normalized.length > 0 ? normalized : null + } + + private normalizeKeyPath(raw: string): string { + if (!raw) { + return '' + } + + const segments = raw.split(/[\\/]+/) + const safeSegments: string[] = [] + + for (const segment of segments) { + const trimmed = segment.trim() + if (!trimmed || trimmed === '.' || trimmed === '..') { + continue + } + safeSegments.push(trimmed) + } + + return safeSegments.join('/') + } + + private resolveThumbnailStorageKey(record: PhotoAssetRecord, remotePrefix: string | null): string | null { + const thumbnailUrl = record.manifest?.data?.thumbnailUrl + if (!thumbnailUrl) { + return null + } + + const photoId = record.photoId ?? record.manifest?.data?.id + if (!photoId) { + return null + } + + const fileName = `${photoId}${DEFAULT_THUMBNAIL_EXTENSION}` + if (!remotePrefix) { + return fileName + } + + return this.joinStorageSegments(remotePrefix, fileName) + } + + private resolveThumbnailRemotePrefix(storageConfig: StorageConfig): string | null { + const directory = this.normalizeStorageSegment(DEFAULT_THUMBNAIL_DIRECTORY) + if (!directory) { + return null + } + + if (storageConfig.provider === 's3') { + const base = this.normalizeStorageSegment(storageConfig.prefix) + return this.joinStorageSegments(base, directory) + } + + if (storageConfig.provider === 'github') { + return directory + } + + return directory + } + + private normalizeStorageSegment(value?: string | null): string | null { + if (typeof value !== 'string') { + return null + } + + const trimmed = value.trim() + if (!trimmed) { + return null + } + + const normalized = trimmed.replaceAll('\\', '/').replaceAll(/^\/+|\/+$/, '') + return normalized.length > 0 ? normalized : null + } + + private joinStorageSegments(...segments: Array): string { + const filtered: string[] = [] + for (const segment of segments) { + if (!segment) { + continue + } + filtered.push(segment.replaceAll(/^\/+|\/+$/, '')) + } + + if (filtered.length === 0) { + return '' + } + + return filtered.join('/') } } diff --git a/be/apps/core/src/modules/photo/photo-storage.service.ts b/be/apps/core/src/modules/photo/photo-storage.service.ts index ef76d8cf..3f434710 100644 --- a/be/apps/core/src/modules/photo/photo-storage.service.ts +++ b/be/apps/core/src/modules/photo/photo-storage.service.ts @@ -1,18 +1,7 @@ import type { BuilderConfig, StorageConfig } from '@afilmory/builder' import { createDefaultBuilderConfig, StorageFactory } from '@afilmory/builder' -import { - EagleStorageProvider, - GitHubStorageProvider, - LocalStorageProvider, - S3StorageProvider, -} from '@afilmory/builder/storage/index.js' -import type { - EagleConfig, - EagleRule, - GitHubConfig, - LocalConfig, - S3Config, -} from '@afilmory/builder/storage/interfaces.js' +import { GitHubStorageProvider, S3StorageProvider } from '@afilmory/builder/storage/index.js' +import type { GitHubConfig, S3Config } from '@afilmory/builder/storage/interfaces.js' import { BizException, ErrorCode } from 'core/errors' import type { BuilderStorageProvider } from 'core/modules/setting/storage-provider.utils' import { injectable } from 'tsyringe' @@ -56,6 +45,8 @@ export class PhotoStorageService { builder: ReturnType, storageConfig: StorageConfig, ): void { + this.assertProviderSupported(storageConfig.provider) + switch (storageConfig.provider) { case 's3': { builder.registerStorageProvider('s3', (config) => new S3StorageProvider(config as S3Config)) @@ -65,14 +56,6 @@ export class PhotoStorageService { builder.registerStorageProvider('github', (config) => new GitHubStorageProvider(config as GitHubConfig)) break } - case 'local': { - builder.registerStorageProvider('local', (config) => new LocalStorageProvider(config as LocalConfig)) - break - } - case 'eagle': { - builder.registerStorageProvider('eagle', (config) => new EagleStorageProvider(config as EagleConfig)) - break - } default: { const provider = (storageConfig as StorageConfig)?.provider as string const registered = StorageFactory.getRegisteredProviders() @@ -86,6 +69,8 @@ export class PhotoStorageService { } private mapProviderToStorageConfig(provider: BuilderStorageProvider): StorageConfig { + this.assertProviderSupported(provider.type) + const config = provider.config ?? {} switch (provider.type) { case 's3': { @@ -156,52 +141,6 @@ export class PhotoStorageService { return result } - case 'local': { - const basePath = this.normalizeString(config.basePath) ?? this.normalizeString(config.path) - - const resolvedBasePath = this.requireString( - basePath, - 'Active local storage provider is missing `basePath`. Please provide a valid path to your photo directory.', - ) - - const result: LocalConfig = { - provider: 'local', - basePath: resolvedBasePath, - } - - const baseUrl = this.normalizeString(config.baseUrl) - if (baseUrl) result.baseUrl = baseUrl - const distPath = this.normalizeString(config.distPath) - if (distPath) result.distPath = distPath - const excludeRegex = this.normalizeString(config.excludeRegex) - if (excludeRegex) result.excludeRegex = excludeRegex - const maxFileLimit = this.parseNumber(config.maxFileLimit) - if (typeof maxFileLimit === 'number') result.maxFileLimit = maxFileLimit - - return result - } - case 'eagle': { - const libraryPath = this.requireString( - config.libraryPath, - 'Active Eagle storage provider is missing `libraryPath`. Provide the path to your Eagle library.', - ) - - const result: EagleConfig = { - provider: 'eagle', - libraryPath, - } - - const distPath = this.normalizeString(config.distPath) - if (distPath) result.distPath = distPath - const baseUrl = this.normalizeString(config.baseUrl) - if (baseUrl) result.baseUrl = baseUrl - const includeRules = this.parseJsonArray(config.include) - if (includeRules) result.include = includeRules - const excludeRules = this.parseJsonArray(config.exclude) - if (excludeRules) result.exclude = excludeRules - - return result - } default: { throw new BizException(ErrorCode.COMMON_BAD_REQUEST, { message: `Unsupported storage provider type: ${provider.type}`, @@ -210,6 +149,14 @@ export class PhotoStorageService { } } + private assertProviderSupported(provider: string): void { + if (provider === 'local' || provider === 'eagle') { + throw new BizException(ErrorCode.COMMON_BAD_REQUEST, { + message: `云端服务不支持 ${provider === 'local' ? 'Local' : 'Eagle'} 存储提供商`, + }) + } + } + private normalizeString(value?: string | null): string | undefined { if (typeof value !== 'string') { return undefined @@ -258,24 +205,6 @@ export class PhotoStorageService { return undefined } - private parseJsonArray(value?: string | null): T[] | undefined { - const normalized = this.normalizeString(value) - if (!normalized) { - return undefined - } - - try { - const parsed = JSON.parse(normalized) - if (Array.isArray(parsed)) { - return parsed as T[] - } - } catch { - /* ignore parse errors */ - } - - return undefined - } - private requireString(value: string | undefined | null, message: string): string { const normalized = this.normalizeString(value) if (!normalized) { diff --git a/be/apps/core/src/modules/photo/photo.controller.ts b/be/apps/core/src/modules/photo/photo.controller.ts index e9068550..176d2516 100644 --- a/be/apps/core/src/modules/photo/photo.controller.ts +++ b/be/apps/core/src/modules/photo/photo.controller.ts @@ -35,7 +35,6 @@ export class PhotoController { @Post('assets/upload') async uploadAssets(@ContextParam() context: Context) { const payload = await context.req.parseBody() - const directory = typeof payload.directory === 'string' ? payload.directory : null const files: File[] = [] for (const value of Object.values(payload)) { @@ -61,7 +60,6 @@ export class PhotoController { filename: file.name, buffer: Buffer.from(await file.arrayBuffer()), contentType: file.type || undefined, - directory, })), ) diff --git a/be/apps/core/src/modules/photo/photo.service.ts b/be/apps/core/src/modules/photo/photo.service.ts index af490316..6810cf44 100644 --- a/be/apps/core/src/modules/photo/photo.service.ts +++ b/be/apps/core/src/modules/photo/photo.service.ts @@ -7,7 +7,12 @@ import type { StorageConfig, StorageObject, } from '@afilmory/builder' -import { AfilmoryBuilder, processPhotoWithPipeline } from '@afilmory/builder' +import { + AfilmoryBuilder, + processPhotoWithPipeline, + THUMBNAIL_PLUGIN_SYMBOL, + thumbnailStoragePlugin, +} from '@afilmory/builder' import type { Logger as BuilderLogger } from '@afilmory/builder/logger/index.js' import type { PhotoProcessingLoggers } from '@afilmory/builder/photo/index.js' import { createPhotoProcessingLoggers, setGlobalLoggers } from '@afilmory/builder/photo/index.js' @@ -38,7 +43,8 @@ export class PhotoBuilderService { private photoLoggers: PhotoProcessingLoggers | null = null createBuilder(config: BuilderConfig): AfilmoryBuilder { - return new AfilmoryBuilder(config) + const enhancedConfig = this.ensureThumbnailPlugin(config) + return new AfilmoryBuilder(enhancedConfig) } applyStorageConfig(builder: AfilmoryBuilder, config: StorageConfig): void { @@ -139,4 +145,25 @@ export class PhotoBuilderService { return result } + + private ensureThumbnailPlugin(config: BuilderConfig): BuilderConfig { + const existingPlugins = config.plugins ?? [] + const hasPlugin = existingPlugins.some((entry) => { + // Check for the unique Symbol identifier for reliable detection + if (typeof entry === 'object' && entry !== null && THUMBNAIL_PLUGIN_SYMBOL in entry) { + return true + } + // Fallback: check by name property for backward compatibility + return entry?.name === 'afilmory:thumbnail-storage' + }) + + if (hasPlugin) { + return config + } + + return { + ...config, + plugins: [...existingPlugins, thumbnailStoragePlugin()], + } + } } diff --git a/be/apps/core/src/modules/reaction/reaction.controller.ts b/be/apps/core/src/modules/reaction/reaction.controller.ts new file mode 100644 index 00000000..8a1b571c --- /dev/null +++ b/be/apps/core/src/modules/reaction/reaction.controller.ts @@ -0,0 +1,50 @@ +import { Body, Controller, Get, Post, Query } from '@afilmory/framework' +import { BizException, ErrorCode } from 'core/errors' + +import { ReactionDto } from './reaction.dto' +import { ReactionService } from './reaction.service' + +@Controller('reactions') +export class ReactionController { + constructor(private readonly reactionService: ReactionService) {} + + @Post('/') + async addReaction(@Body() body: ReactionDto) { + const { refKey, reaction } = body + + await this.reactionService.addReaction(refKey, reaction) + } + + @Get('/') + async getReactions(@Query() query: { refKey?: string }): Promise< + Array<{ + id: string + refKey: string + reaction: string + createdAt: string + }> + > { + const { refKey } = query + + if (!refKey) { + throw new BizException(ErrorCode.COMMON_BAD_REQUEST, { + message: 'refKey query parameter is required', + }) + } + + return await this.reactionService.getReactionsByRefKey(refKey) + } + + @Get('/stats') + async getReactionStats(@Query() query: { refKey?: string }): Promise> { + const { refKey } = query + + if (!refKey) { + throw new BizException(ErrorCode.COMMON_BAD_REQUEST, { + message: 'refKey query parameter is required', + }) + } + + return await this.reactionService.getReactionStats(refKey) + } +} diff --git a/be/apps/core/src/modules/reaction/reaction.dto.ts b/be/apps/core/src/modules/reaction/reaction.dto.ts new file mode 100644 index 00000000..9ee60dcd --- /dev/null +++ b/be/apps/core/src/modules/reaction/reaction.dto.ts @@ -0,0 +1,8 @@ +import { z } from 'zod' + +export const ReactionDto = z.object({ + refKey: z.string(), + reaction: z.string().min(1).max(20), +}) + +export type ReactionDto = z.infer diff --git a/be/apps/core/src/modules/reaction/reaction.module.ts b/be/apps/core/src/modules/reaction/reaction.module.ts new file mode 100644 index 00000000..3e8526a3 --- /dev/null +++ b/be/apps/core/src/modules/reaction/reaction.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@afilmory/framework' + +import { ReactionController } from './reaction.controller' +import { ReactionService } from './reaction.service' + +@Module({ + controllers: [ReactionController], + providers: [ReactionService], +}) +export class ReactionModule {} diff --git a/be/apps/core/src/modules/reaction/reaction.service.ts b/be/apps/core/src/modules/reaction/reaction.service.ts new file mode 100644 index 00000000..7aaebb65 --- /dev/null +++ b/be/apps/core/src/modules/reaction/reaction.service.ts @@ -0,0 +1,78 @@ +import { reactions } from '@afilmory/db' +import { BizException, ErrorCode } from 'core/errors' +import { requireTenantContext } from 'core/modules/tenant/tenant.context' +import { eq } from 'drizzle-orm' +import { injectable } from 'tsyringe' + +import { DbAccessor } from '../../database/database.provider' + +@injectable() +export class ReactionService { + constructor(private readonly dbAccessor: DbAccessor) {} + + async addReaction(refKey: string, reaction: string): Promise { + const tenant = requireTenantContext() + const db = this.dbAccessor.get() + + // Check if photo exists (you might want to validate this differently based on your photo storage) + // For now, we'll just add the reaction assuming the refKey is valid + + try { + await db.insert(reactions).values({ + tenantId: tenant.tenant.id, + refKey, + reaction, + }) + } catch (error) { + console.error('Failed to add reaction:', error) + throw new BizException(ErrorCode.COMMON_BAD_REQUEST, { + message: 'Failed to add reaction', + }) + } + } + + async getReactionsByRefKey(refKey: string): Promise< + Array<{ + id: string + refKey: string + reaction: string + createdAt: string + }> + > { + requireTenantContext() + const db = this.dbAccessor.get() + + const records = await db + .select({ + id: reactions.id, + refKey: reactions.refKey, + reaction: reactions.reaction, + createdAt: reactions.createdAt, + }) + .from(reactions) + .where(eq(reactions.refKey, refKey)) + .orderBy(reactions.createdAt) + + return records + } + + async getReactionStats(refKey: string): Promise> { + requireTenantContext() + const db = this.dbAccessor.get() + + const reactionRecords = await db + .select({ + reaction: reactions.reaction, + }) + .from(reactions) + .where(eq(reactions.refKey, refKey)) + + return reactionRecords.reduce( + (acc, record) => { + acc[record.reaction] = (acc[record.reaction] || 0) + 1 + return acc + }, + {} as Record, + ) + } +} diff --git a/be/apps/core/src/modules/setting/storage-provider.utils.ts b/be/apps/core/src/modules/setting/storage-provider.utils.ts index c38f50b8..417f73a3 100644 --- a/be/apps/core/src/modules/setting/storage-provider.utils.ts +++ b/be/apps/core/src/modules/setting/storage-provider.utils.ts @@ -38,7 +38,7 @@ function normalizeProvider(input: unknown): BuilderStorageProvider | null { return { id: typeof record.id === 'string' && record.id.trim().length > 0 ? record.id.trim() : randomUUID(), name: typeof record.name === 'string' && record.name.trim().length > 0 ? record.name.trim() : '未命名存储', - type: typeof record.type === 'string' ? record.type : 'local', + type: typeof record.type === 'string' ? record.type : 's3', config: normalizeConfig(record.config), createdAt: typeof record.createdAt === 'string' ? record.createdAt : now, updatedAt: typeof record.updatedAt === 'string' ? record.updatedAt : now, diff --git a/be/apps/core/src/modules/system-setting/super-admin-setting.service.ts b/be/apps/core/src/modules/system-setting/super-admin-setting.service.ts index d1b891cd..bd9ca5ce 100644 --- a/be/apps/core/src/modules/system-setting/super-admin-setting.service.ts +++ b/be/apps/core/src/modules/system-setting/super-admin-setting.service.ts @@ -125,6 +125,27 @@ export class SuperAdminSettingService { return current } + async ensureRegistrationAllowed(): Promise { + const settings = await this.getSettings() + + if (!settings.allowRegistration) { + throw new BizException(ErrorCode.AUTH_FORBIDDEN, { + message: '当前已关闭用户注册,请联系管理员获取访问权限。', + }) + } + + if (settings.maxRegistrableUsers === null) { + return + } + + const totalUsers = await this.getTotalUserCount() + if (totalUsers >= settings.maxRegistrableUsers) { + throw new BizException(ErrorCode.AUTH_FORBIDDEN, { + message: '用户注册数量已达到上限,请联系管理员。', + }) + } + } + private parseSetting(raw: unknown, schema: ZodType, defaultValue: T): T { if (raw === null || raw === undefined) { return defaultValue diff --git a/be/apps/core/src/modules/system-setting/super-admin-setting.ui-schema.ts b/be/apps/core/src/modules/system-setting/super-admin-setting.ui-schema.ts index f89f11c0..a6b61508 100644 --- a/be/apps/core/src/modules/system-setting/super-admin-setting.ui-schema.ts +++ b/be/apps/core/src/modules/system-setting/super-admin-setting.ui-schema.ts @@ -23,8 +23,6 @@ export const SUPER_ADMIN_SETTING_UI_SCHEMA: UiSchema = { key: 'allowRegistration', component: { type: 'switch', - trueLabel: '允许', - falseLabel: '禁止', }, }, { @@ -35,8 +33,6 @@ export const SUPER_ADMIN_SETTING_UI_SCHEMA: UiSchema = { key: 'localProviderEnabled', component: { type: 'switch', - trueLabel: '启用', - falseLabel: '禁用', }, }, { diff --git a/be/apps/core/vite.config.ts b/be/apps/core/vite.config.ts index ef281904..9599c732 100644 --- a/be/apps/core/vite.config.ts +++ b/be/apps/core/vite.config.ts @@ -1,9 +1,11 @@ -import { builtinModules } from 'node:module' +import { readFile, writeFile } from 'node:fs/promises' +import { builtinModules, createRequire } from 'node:module' import { dirname, resolve } from 'node:path' import { fileURLToPath } from 'node:url' import swc from 'unplugin-swc' import { defineConfig } from 'vite' +import { analyzer } from 'vite-bundle-analyzer' import tsconfigPaths from 'vite-tsconfig-paths' const NODE_BUILT_IN_MODULES = builtinModules.filter((m) => !m.startsWith('_')) @@ -11,8 +13,47 @@ NODE_BUILT_IN_MODULES.push(...NODE_BUILT_IN_MODULES.map((m) => `node:${m}`)) const __dirname = dirname(fileURLToPath(import.meta.url)) +const external = ['sharp', 'nodejs-snowflake', 'ioredis', 'heic-convert'] +function generateExternalsPackageJson (externals: string[]) { + const req = createRequire(import.meta.url) + let outDirAbs = '' + const plugin: import('vite').Plugin = { + name: 'generate-externals-package-json', + apply: 'build', + configResolved(config) { + outDirAbs = resolve(config.root, config.build.outDir) + }, + async closeBundle() { + const dependencies: Record = {} + for (const name of externals) { + try { + const pkgJsonPath = req.resolve(`${name}/package.json`) + const raw = await readFile(pkgJsonPath, 'utf-8') + const parsed = JSON.parse(raw) + if (parsed?.version) { + dependencies[name] = parsed.version as string + } + } catch { + continue + } + } + const content = { + private: true, + type: 'module', + dependencies, + } + await writeFile(resolve(outDirAbs, 'package.json'), JSON.stringify(content, null, 2)) + }, + } + return plugin +} export default defineConfig({ - plugins: [tsconfigPaths(), swc.vite()], + plugins: [ + tsconfigPaths(), + swc.vite(), + analyzer({ enabled: process.env.ANALYZER === 'true' }), + generateExternalsPackageJson(external), + ], esbuild: false, resolve: { alias: { @@ -22,6 +63,7 @@ export default defineConfig({ }, ssr: { noExternal: true, + external, }, build: { ssr: true, diff --git a/be/apps/dashboard/package.json b/be/apps/dashboard/package.json index 5a31f39b..f0f69924 100644 --- a/be/apps/dashboard/package.json +++ b/be/apps/dashboard/package.json @@ -35,21 +35,21 @@ "@react-hook/window-size": "3.1.1", "@remixicon/react": "4.7.0", "@tanstack/react-query": "5.90.5", - "better-auth": "1.3.29", + "better-auth": "1.3.34", "class-variance-authority": "0.7.1", "clsx": "2.1.1", "es-toolkit": "1.41.0", "foxact": "0.2.49", - "immer": "10.1.3", + "immer": "10.2.0", "jotai": "2.15.0", - "lucide-react": "0.547.0", + "lucide-react": "0.552.0", "motion": "12.23.24", "nanoid": "5.1.6", - "ofetch": "1.4.1", + "ofetch": "1.5.0", "radix-ui": "1.4.3", "react": "19.2.0", "react-dom": "19.2.0", - "react-router": "7.9.4", + "react-router": "7.9.5", "react-scan": "0.4.3", "sonner": "2.0.7", "tailwind-merge": "3.3.1", @@ -62,7 +62,7 @@ "@tailwindcss/postcss": "4.1.16", "@tailwindcss/typography": "0.5.19", "@tailwindcss/vite": "4.1.16", - "@types/node": "24.9.1", + "@types/node": "24.9.2", "@types/react": "19.2.2", "@types/react-dom": "19.2.2", "@vitejs/plugin-react": "^5.1.0", diff --git a/be/apps/dashboard/plugins/eslint-recursive-sort.js b/be/apps/dashboard/plugins/eslint-recursive-sort.js index d451554b..d0e15d55 100644 --- a/be/apps/dashboard/plugins/eslint-recursive-sort.js +++ b/be/apps/dashboard/plugins/eslint-recursive-sort.js @@ -1,4 +1,4 @@ -const sortObjectKeys = (obj) => { +function sortObjectKeys(obj) { if (typeof obj !== 'object' || obj === null) { return obj } diff --git a/be/apps/dashboard/src/App.tsx b/be/apps/dashboard/src/App.tsx index 65657471..e15aae36 100644 --- a/be/apps/dashboard/src/App.tsx +++ b/be/apps/dashboard/src/App.tsx @@ -13,14 +13,14 @@ export const App: FC = () => { ) } -const AppLayer = () => { +function AppLayer() { usePageRedirect() const appIsReady = true return appIsReady ? : } -const AppSkeleton = () => { +function AppSkeleton() { return null } export default App diff --git a/be/apps/dashboard/src/atoms/auth.ts b/be/apps/dashboard/src/atoms/auth.ts index 44c488b8..b872339c 100644 --- a/be/apps/dashboard/src/atoms/auth.ts +++ b/be/apps/dashboard/src/atoms/auth.ts @@ -9,22 +9,22 @@ export const [authUserAtom, useAuthUser, useAuthUserValue, useSetAuthUser, getAu createAtomHooks(baseAuthUserAtom) // Selectors -export const useIsAuthenticated = () => { +export function useIsAuthenticated() { const user = useAuthUserValue() return !!user } -export const useUserRole = () => { +export function useUserRole() { const user = useAuthUserValue() return user?.role ?? null } -export const useIsAdmin = () => { +export function useIsAdmin() { const user = useAuthUserValue() return user?.role === 'admin' || user?.role === 'superadmin' } -export const useIsSuperAdmin = () => { +export function useIsSuperAdmin() { const user = useAuthUserValue() return user?.role === 'superadmin' } diff --git a/be/apps/dashboard/src/atoms/context-menu.ts b/be/apps/dashboard/src/atoms/context-menu.ts index aeee4cf1..a00d213f 100644 --- a/be/apps/dashboard/src/atoms/context-menu.ts +++ b/be/apps/dashboard/src/atoms/context-menu.ts @@ -20,11 +20,11 @@ export const [contextMenuAtom, useContextMenuState, useContextMenuValue, useSetC atom({ open: false }), ) -const useShowWebContextMenu = () => { +function useShowWebContextMenu() { const setContextMenu = useSetContextMenu() const showWebContextMenu = useCallback( - async (menuItems: Array, e: MouseEvent | React.MouseEvent) => { + async (menuItems: FollowMenuItem[], e: MouseEvent | React.MouseEvent) => { const abortController = new AbortController() const resolvers = Promise.withResolvers() setContextMenu({ @@ -75,11 +75,11 @@ export enum MenuItemType { Action, } -export const useShowContextMenu = () => { +export function useShowContextMenu() { const showWebContextMenu = useShowWebContextMenu() const showContextMenu = useCallback( - async (inputMenu: Array, e: MouseEvent | React.MouseEvent) => { + async (inputMenu: MenuItemInput[], e: MouseEvent | React.MouseEvent) => { const menuItems = filterNullableMenuItems(inputMenu) e.preventDefault() e.stopPropagation() diff --git a/be/apps/dashboard/src/atoms/route.ts b/be/apps/dashboard/src/atoms/route.ts index e1653fd2..07d51955 100644 --- a/be/apps/dashboard/src/atoms/route.ts +++ b/be/apps/dashboard/src/atoms/route.ts @@ -25,7 +25,7 @@ export const [routeAtom, , , , getReadonlyRoute, setRoute] = createAtomHooks( }), ) -export const useReadonlyRouteSelector = (selector: (route: RouteAtom) => T): T => { +export function useReadonlyRouteSelector(selector: (route: RouteAtom) => T): T { const memoizedAtom = useMemo(() => selectAtom(routeAtom, (route) => selector(route)), [selector]) return useAtomValue(memoizedAtom) diff --git a/be/apps/dashboard/src/components/common/GlassPanel.tsx b/be/apps/dashboard/src/components/common/GlassPanel.tsx new file mode 100644 index 00000000..f8b83313 --- /dev/null +++ b/be/apps/dashboard/src/components/common/GlassPanel.tsx @@ -0,0 +1,16 @@ +import { clsxm } from '@afilmory/utils' +import type { ReactNode } from 'react' + +export function LinearBorderPanel({ className, children }: { className?: string; children: ReactNode }) { + return ( +
+ {/* Linear gradient borders - sharp edges */} +
+
+
+
+ +
{children}
+
+ ) +} diff --git a/be/apps/dashboard/src/components/common/NotFound.tsx b/be/apps/dashboard/src/components/common/NotFound.tsx index 1fc79db7..8ebee911 100644 --- a/be/apps/dashboard/src/components/common/NotFound.tsx +++ b/be/apps/dashboard/src/components/common/NotFound.tsx @@ -1,7 +1,7 @@ import { Button } from '@afilmory/ui' import { useLocation, useNavigate } from 'react-router' -export const NotFound = () => { +export function NotFound() { const location = useLocation() const navigate = useNavigate() diff --git a/be/apps/dashboard/src/components/layouts/MainPageLayout.tsx b/be/apps/dashboard/src/components/layouts/MainPageLayout.tsx index 759ecb02..ab1330c8 100644 --- a/be/apps/dashboard/src/components/layouts/MainPageLayout.tsx +++ b/be/apps/dashboard/src/components/layouts/MainPageLayout.tsx @@ -23,7 +23,7 @@ type MainPageLayoutContextValue = { const MainPageLayoutContext = createContext(null) -export const useMainPageLayout = () => { +export function useMainPageLayout() { const context = use(MainPageLayoutContext) if (!context) { @@ -41,7 +41,7 @@ type MainPageLayoutProps = { children: ReactNode } -const MainPageLayoutBase = ({ title, description, actions, footer, children }: MainPageLayoutProps) => { +function MainPageLayoutBase({ title, description, actions, footer, children }: MainPageLayoutProps) { const [headerActionsContainer, setHeaderActionsContainer] = useState(null) const [portalMountCount, setPortalMountCount] = useState(0) const [headerActionState, setHeaderActionState] = useState(defaultHeaderActionState) @@ -109,7 +109,7 @@ type MainPageLayoutActionsProps = { children: ReactNode } -const MainPageLayoutActions = ({ children }: MainPageLayoutActionsProps) => { +function MainPageLayoutActions({ children }: MainPageLayoutActionsProps) { const { headerActionsContainer, registerPortalPresence } = useMainPageLayout() useEffect(() => { diff --git a/be/apps/dashboard/src/components/navigation/PageTabs.tsx b/be/apps/dashboard/src/components/navigation/PageTabs.tsx index ebf619e9..d3f8e930 100644 --- a/be/apps/dashboard/src/components/navigation/PageTabs.tsx +++ b/be/apps/dashboard/src/components/navigation/PageTabs.tsx @@ -18,7 +18,7 @@ export interface PageTabsProps { className?: string } -export const PageTabs = ({ items, activeId, onSelect, className }: PageTabsProps) => { +export function PageTabs({ items, activeId, onSelect, className }: PageTabsProps) { const renderTabContent = (selected: boolean, label: ReactNode) => ( { +}: UseBlockOptions) { const promptIdRef = useRef(null) const isPromptOpenRef = useRef(false) diff --git a/be/apps/dashboard/src/hooks/usePageRedirect.ts b/be/apps/dashboard/src/hooks/usePageRedirect.ts index 55695d81..fe740c93 100644 --- a/be/apps/dashboard/src/hooks/usePageRedirect.ts +++ b/be/apps/dashboard/src/hooks/usePageRedirect.ts @@ -21,7 +21,7 @@ const AUTH_FAILURE_STATUSES = new Set([401, 403, 419]) const PUBLIC_PATHS = new Set([DEFAULT_LOGIN_PATH, DEFAULT_ONBOARDING_PATH]) -export const usePageRedirect = () => { +export function usePageRedirect() { const location = useLocation() const navigate = useNavigate() const queryClient = useQueryClient() diff --git a/be/apps/dashboard/src/lib/case.ts b/be/apps/dashboard/src/lib/case.ts index d345895f..4e37954f 100644 --- a/be/apps/dashboard/src/lib/case.ts +++ b/be/apps/dashboard/src/lib/case.ts @@ -1,6 +1,6 @@ const CAMELIZE_PATTERN = /[_.-](\w|$)/g -const camelCase = (value: string): string => { +function camelCase(value: string): string { if (!value || (!value.includes('_') && !value.includes('-') && !value.includes('.'))) { return value } @@ -8,7 +8,7 @@ const camelCase = (value: string): string => { return value.replaceAll(CAMELIZE_PATTERN, (_match, group: string) => group.toUpperCase()) } -const isPlainObject = (value: unknown): value is Record => { +function isPlainObject(value: unknown): value is Record { if (typeof value !== 'object' || value === null) { return false } @@ -17,7 +17,7 @@ const isPlainObject = (value: unknown): value is Record => { return prototype === Object.prototype || prototype === null } -export const camelCaseKeys = (input: unknown): T => { +export function camelCaseKeys(input: unknown): T { if (Array.isArray(input)) { return input.map((item) => camelCaseKeys(item)) as unknown as T } diff --git a/be/apps/dashboard/src/lib/dev.tsx b/be/apps/dashboard/src/lib/dev.tsx index a84c422f..e186951e 100644 --- a/be/apps/dashboard/src/lib/dev.tsx +++ b/be/apps/dashboard/src/lib/dev.tsx @@ -1,5 +1,5 @@ declare const APP_DEV_CWD: string -export const attachOpenInEditor = (stack: string) => { +export function attachOpenInEditor(stack: string) { const lines = stack.split('\n') return lines.map((line) => { // A line like this: at App (http://localhost:5173/src/App.tsx?t=1720527056591:41:9) @@ -47,6 +47,6 @@ export const attachOpenInEditor = (stack: string) => { }) } // http://localhost:5173/src/App.tsx?t=1720527056591:41:9 -const openInEditor = (file: string) => { +function openInEditor(file: string) { fetch(`/__open-in-editor?file=${encodeURIComponent(`${file}`)}`) } diff --git a/be/apps/dashboard/src/lib/dom.ts b/be/apps/dashboard/src/lib/dom.ts index f2ef785b..dee0b3ae 100644 --- a/be/apps/dashboard/src/lib/dom.ts +++ b/be/apps/dashboard/src/lib/dom.ts @@ -4,7 +4,7 @@ export const stopPropagation: ReactEventHandler = (e) => e.stopPropagation( export const preventDefault: ReactEventHandler = (e) => e.preventDefault() -export const nextFrame = (fn: (...args: any[]) => any) => { +export function nextFrame(fn: (...args: any[]) => any) { requestAnimationFrame(() => { requestAnimationFrame(() => { fn() @@ -12,7 +12,7 @@ export const nextFrame = (fn: (...args: any[]) => any) => { }) } -export const getElementTop = (element: HTMLElement) => { +export function getElementTop(element: HTMLElement) { let actualTop = element.offsetTop let current = element.offsetParent as HTMLElement while (current !== null) { diff --git a/be/apps/dashboard/src/lib/jotai.ts b/be/apps/dashboard/src/lib/jotai.ts index e5a816c5..4d4282a5 100644 --- a/be/apps/dashboard/src/lib/jotai.ts +++ b/be/apps/dashboard/src/lib/jotai.ts @@ -5,24 +5,26 @@ import { useMemo } from 'react' export const jotaiStore = createStore() -export const createAtomAccessor = (atom: PrimitiveAtom) => - [() => jotaiStore.get(atom), (value: T) => jotaiStore.set(atom, value)] as const +export function createAtomAccessor(atom: PrimitiveAtom) { + return [() => jotaiStore.get(atom), (value: T) => jotaiStore.set(atom, value)] as const +} const options = { store: jotaiStore } /** * @param atom - jotai * @returns - [atom, useAtom, useAtomValue, useSetAtom, jotaiStore.get, jotaiStore.set] */ -export const createAtomHooks = (atom: PrimitiveAtom) => - [ +export function createAtomHooks(atom: PrimitiveAtom) { + return [ atom, () => useAtom(atom, options), () => useAtomValue(atom, options), () => useSetAtom(atom, options), ...createAtomAccessor(atom), ] as const +} -export const createAtomSelector = (atom: Atom) => { +export function createAtomSelector(atom: Atom) { const useHook = (selector: (a: T) => R) => { const memoizedAtom = useMemo(() => selectAtom(atom, (value) => selector(value)), [selector]) diff --git a/be/apps/dashboard/src/lib/ns.ts b/be/apps/dashboard/src/lib/ns.ts index 5bb6f061..167c82cf 100644 --- a/be/apps/dashboard/src/lib/ns.ts +++ b/be/apps/dashboard/src/lib/ns.ts @@ -1,7 +1,7 @@ const ns = 'app' export const getStorageNS = (key: string) => `${ns}:${key}` -export const clearStorage = () => { +export function clearStorage() { for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i) if (key && key.startsWith(ns)) { diff --git a/be/apps/dashboard/src/modules/auth/api/login.ts b/be/apps/dashboard/src/modules/auth/api/login.ts index adff45f9..63df400f 100644 --- a/be/apps/dashboard/src/modules/auth/api/login.ts +++ b/be/apps/dashboard/src/modules/auth/api/login.ts @@ -16,7 +16,7 @@ export interface LoginResponse extends SessionResponse { * @param data - Login credentials with email and password * @returns Session response with user and session data */ -export const login = async (data: LoginRequest): Promise => { +export async function login(data: LoginRequest): Promise { // better-auth returns Response object, we need to parse it const response = await coreApi('/auth/sign-in/email', { method: 'POST', diff --git a/be/apps/dashboard/src/modules/auth/api/session.ts b/be/apps/dashboard/src/modules/auth/api/session.ts index a4d9b405..03ebba9e 100644 --- a/be/apps/dashboard/src/modules/auth/api/session.ts +++ b/be/apps/dashboard/src/modules/auth/api/session.ts @@ -9,7 +9,8 @@ export type SessionResponse = { export const AUTH_SESSION_QUERY_KEY = ['auth', 'session'] as const -export const fetchSession = async () => - await coreApi('/auth/session', { +export async function fetchSession() { + return await coreApi('/auth/session', { method: 'GET', }) +} diff --git a/be/apps/dashboard/src/modules/auth/hooks/useLogin.ts b/be/apps/dashboard/src/modules/auth/hooks/useLogin.ts index d789e8b2..a33a5ce3 100644 --- a/be/apps/dashboard/src/modules/auth/hooks/useLogin.ts +++ b/be/apps/dashboard/src/modules/auth/hooks/useLogin.ts @@ -14,7 +14,7 @@ export interface LoginRequest { rememberMe?: boolean } -export const useLogin = () => { +export function useLogin() { const navigate = useNavigate() const queryClient = useQueryClient() const setAuthUser = useSetAuthUser() diff --git a/be/apps/dashboard/src/modules/dashboard/api.ts b/be/apps/dashboard/src/modules/dashboard/api.ts new file mode 100644 index 00000000..0edf2bc8 --- /dev/null +++ b/be/apps/dashboard/src/modules/dashboard/api.ts @@ -0,0 +1,14 @@ +import { coreApi } from '~/lib/api-client' +import { camelCaseKeys } from '~/lib/case' + +import type { DashboardOverviewResponse } from './types' + +const DASHBOARD_OVERVIEW_ENDPOINT = '/dashboard/overview' + +export async function fetchDashboardOverview() { + return camelCaseKeys( + await coreApi(DASHBOARD_OVERVIEW_ENDPOINT, { + method: 'GET', + }), + ) +} diff --git a/be/apps/dashboard/src/modules/dashboard/components/DashboardOverview.tsx b/be/apps/dashboard/src/modules/dashboard/components/DashboardOverview.tsx new file mode 100644 index 00000000..ed1d0a70 --- /dev/null +++ b/be/apps/dashboard/src/modules/dashboard/components/DashboardOverview.tsx @@ -0,0 +1,376 @@ +import { Spring } from '@afilmory/utils' +import { m } from 'motion/react' + +import { LinearBorderPanel } from '~/components/common/GlassPanel' +import { MainPageLayout } from '~/components/layouts/MainPageLayout' + +import { useDashboardOverviewQuery } from '../hooks' +import type { DashboardRecentActivityItem } from '../types' + +const compactNumberFormatter = new Intl.NumberFormat('zh-CN', { + notation: 'compact', + maximumFractionDigits: 1, +}) + +const plainNumberFormatter = new Intl.NumberFormat('zh-CN') + +const percentFormatter = new Intl.NumberFormat('zh-CN', { + style: 'percent', + maximumFractionDigits: 1, +}) + +const relativeTimeFormatter = new Intl.RelativeTimeFormat('zh-CN', { numeric: 'auto' }) + +const dateTimeFormatter = new Intl.DateTimeFormat('zh-CN', { + dateStyle: 'medium', + timeStyle: 'short', +}) + +function formatCompactNumber(value: number) { + if (!Number.isFinite(value)) return '--' + if (value === 0) return '0' + return compactNumberFormatter.format(value) +} + +function formatBytes(bytes: number) { + if (!Number.isFinite(bytes) || bytes <= 0) { + return '0 B' + } + + const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'] + let value = bytes + let unitIndex = 0 + + while (value >= 1024 && unitIndex < units.length - 1) { + value /= 1024 + unitIndex += 1 + } + + return `${value.toFixed(value >= 10 || unitIndex === 0 ? 0 : 1)} ${units[unitIndex]}` +} + +type TimeDivision = { + amount: number + unit: Intl.RelativeTimeFormatUnit +} + +const timeDivisions: TimeDivision[] = [ + { amount: 60, unit: 'second' }, + { amount: 60, unit: 'minute' }, + { amount: 24, unit: 'hour' }, + { amount: 7, unit: 'day' }, + { amount: 4.34524, unit: 'week' }, + { amount: 12, unit: 'month' }, + { amount: Number.POSITIVE_INFINITY, unit: 'year' }, +] + +function formatRelativeTime(iso: string | null | undefined) { + if (!iso) return '时间未知' + const date = new Date(iso) + if (Number.isNaN(date.getTime())) { + return '时间未知' + } + + let diffInSeconds = (date.getTime() - Date.now()) / 1000 + for (const division of timeDivisions) { + if (Math.abs(diffInSeconds) < division.amount) { + return relativeTimeFormatter.format(Math.round(diffInSeconds), division.unit) + } + diffInSeconds /= division.amount + } + + return dateTimeFormatter.format(date) +} + +function formatTakenAt(iso: string | null) { + if (!iso) return null + const date = new Date(iso) + if (Number.isNaN(date.getTime())) return null + return dateTimeFormatter.format(date) +} + +const STATUS_META = { + synced: { + label: '已同步', + barClass: 'bg-emerald-400/80', + dotClass: 'bg-emerald-400/90', + badgeClass: 'bg-emerald-500/10 text-emerald-300', + }, + pending: { + label: '处理中', + barClass: 'bg-orange-400/80', + dotClass: 'bg-orange-400/90', + badgeClass: 'bg-orange-500/10 text-orange-300', + }, + conflict: { + label: '需关注', + barClass: 'bg-red-500/80', + dotClass: 'bg-red-500/90', + badgeClass: 'bg-red-500/10 text-red-300', + }, +} satisfies Record< + DashboardRecentActivityItem['syncStatus'], + { label: string; barClass: string; dotClass: string; badgeClass: string } +> + +const EMPTY_STATS = { + totalPhotos: 0, + totalStorageBytes: 0, + thisMonthUploads: 0, + previousMonthUploads: 0, + sync: { + synced: 0, + pending: 0, + conflicts: 0, + }, +} as const + +function ActivitySkeleton() { + return ( +
+
+
+
+
+
+
+
+
+
+ ) +} + +function StatSkeleton() { + return ( + +
+
+
+
+
+ + ) +} + +function ActivityList({ items }: { items: DashboardRecentActivityItem[] }) { + if (items.length === 0) { + return
暂无最近活动,上传照片后即可看到这里的动态。
+ } + + return ( +
+ {items.map((item, index) => { + const statusMeta = STATUS_META[item.syncStatus] + const takenAtText = formatTakenAt(item.takenAt) + + return ( + +
+
+
+ {item.previewUrl ? ( + {item.title} + ) : ( +
+ No Preview +
+ )} +
+
+
{item.title}
+
+ 上传于 {formatRelativeTime(item.createdAt)} + {takenAtText ? ( + <> + + 拍摄时间 {takenAtText} + + ) : null} +
+
+ {item.size != null && item.size > 0 ? formatBytes(item.size) : '大小未知'} + + {item.storageProvider} + + + {statusMeta.label} + +
+ {item.tags.length > 0 ? ( +
+ {item.tags.map((tag) => ( + + {tag} + + ))} +
+ ) : null} +
+
+
+ ID: + {item.photoId} +
+
+
+ ) + })} +
+ ) +} + +export function DashboardOverview() { + const { data, isLoading, isError } = useDashboardOverviewQuery() + + const stats = data?.stats ?? EMPTY_STATS + const statusTotal = stats.sync.synced + stats.sync.pending + stats.sync.conflicts + const syncCompletion = statusTotal === 0 ? null : stats.sync.synced / statusTotal + + const monthlyDelta = stats.thisMonthUploads - stats.previousMonthUploads + let monthlyTrendDescription = '与上月持平' + if (stats.previousMonthUploads === 0) { + monthlyTrendDescription = stats.thisMonthUploads === 0 ? '与上月持平' : '首次出现上传记录' + } else if (monthlyDelta > 0) { + monthlyTrendDescription = `比上月多 ${plainNumberFormatter.format(monthlyDelta)} 张` + } else if (monthlyDelta < 0) { + monthlyTrendDescription = `比上月少 ${plainNumberFormatter.format(Math.abs(monthlyDelta))} 张` + } + + const averageSize = stats.totalPhotos > 0 ? stats.totalStorageBytes / stats.totalPhotos : 0 + + const statCards = [ + { + key: 'total-photos', + label: '照片总数', + value: formatCompactNumber(stats.totalPhotos), + helper: `${plainNumberFormatter.format(stats.totalPhotos)} 张照片`, + }, + { + key: 'storage', + label: '占用存储', + value: formatBytes(stats.totalStorageBytes), + helper: stats.totalPhotos > 0 ? `平均每张 ${formatBytes(averageSize || 0)}` : '暂无照片,存储占用为 0', + }, + { + key: 'this-month', + label: '本月新增', + value: formatCompactNumber(stats.thisMonthUploads), + helper: monthlyTrendDescription, + }, + { + key: 'sync', + label: '同步完成率', + value: syncCompletion === null ? '--' : percentFormatter.format(syncCompletion), + helper: statusTotal + ? `待处理 ${plainNumberFormatter.format(stats.sync.pending)} | 冲突 ${plainNumberFormatter.format(stats.sync.conflicts)}` + : '暂无同步任务', + }, + ] + + const syncSummary = [ + { key: 'synced', value: stats.sync.synced }, + { key: 'pending', value: stats.sync.pending }, + { key: 'conflict', value: stats.sync.conflicts }, + ] as const + + return ( + +
+
+ {isLoading + ? Array.from({ length: 4 }, (_, i) => `skeleton-${i}`).map((key) => ) + : statCards.map((card, index) => ( + + + + {card.label} + +
{card.value}
+
{card.helper}
+
+
+ ))} +
+ +
+ +
+

最近活动

+

+ {data?.recentActivity?.length + ? `展示最近 ${data.recentActivity.length} 次上传和同步记录` + : '还没有任何上传,快来添加第一张照片吧~'} +

+
+ + {isLoading ? ( +
+ {Array.from({ length: 3 }, (_, i) => `activity-skeleton-${i}`).map((key) => ( + + ))} +
+ ) : isError ? ( +
无法获取活动数据,请稍后再试。
+ ) : ( + + )} +
+ + +
+

同步概览

+

了解当前同步状态,及时处理异常项。

+
+ +
+ {syncSummary.map((entry) => { + const meta = STATUS_META[entry.key] + const percent = statusTotal ? Math.round((entry.value / statusTotal) * 100) : 0 + + return ( +
+
+ + + {meta.label} + + + {plainNumberFormatter.format(entry.value)} + {percent}% + +
+
+
0 ? 4 : 0) : 0}%` }} + /> +
+
+ ) + })} +
+ +
+ {statusTotal === 0 + ? '暂无同步任务,添加照片后即可查看同步健康度。' + : syncCompletion !== null && syncCompletion >= 0.85 + ? '同步状态良好,保持当前处理效率即可。' + : '存在待处理或冲突的项目,建议尽快检查同步日志。'} +
+ +
+
+ + ) +} diff --git a/be/apps/dashboard/src/modules/dashboard/hooks.ts b/be/apps/dashboard/src/modules/dashboard/hooks.ts new file mode 100644 index 00000000..f386e973 --- /dev/null +++ b/be/apps/dashboard/src/modules/dashboard/hooks.ts @@ -0,0 +1,14 @@ +import { useQuery } from '@tanstack/react-query' + +import { fetchDashboardOverview } from './api' +import type { DashboardOverviewResponse } from './types' + +export const DASHBOARD_OVERVIEW_QUERY_KEY = ['dashboard', 'overview'] as const + +export function useDashboardOverviewQuery() { + return useQuery({ + queryKey: DASHBOARD_OVERVIEW_QUERY_KEY, + queryFn: fetchDashboardOverview, + staleTime: 60 * 1000, + }) +} diff --git a/be/apps/dashboard/src/modules/dashboard/types.ts b/be/apps/dashboard/src/modules/dashboard/types.ts new file mode 100644 index 00000000..080f995c --- /dev/null +++ b/be/apps/dashboard/src/modules/dashboard/types.ts @@ -0,0 +1,30 @@ +export interface DashboardStats { + totalPhotos: number + totalStorageBytes: number + thisMonthUploads: number + previousMonthUploads: number + sync: { + synced: number + pending: number + conflicts: number + } +} + +export interface DashboardRecentActivityItem { + id: string + photoId: string + title: string + description: string | null + createdAt: string + takenAt: string | null + storageProvider: string + size: number | null + syncStatus: 'pending' | 'synced' | 'conflict' + tags: string[] + previewUrl: string | null +} + +export interface DashboardOverviewResponse { + stats: DashboardStats + recentActivity: DashboardRecentActivityItem[] +} diff --git a/be/apps/dashboard/src/modules/onboarding/api.ts b/be/apps/dashboard/src/modules/onboarding/api.ts index b7f2446a..bebe9957 100644 --- a/be/apps/dashboard/src/modules/onboarding/api.ts +++ b/be/apps/dashboard/src/modules/onboarding/api.ts @@ -30,13 +30,15 @@ export type OnboardingInitResponse = { superAdminUserId: string } -export const getOnboardingStatus = async () => - await coreApi('/onboarding/status', { +export async function getOnboardingStatus() { + return await coreApi('/onboarding/status', { method: 'GET', }) +} -export const postOnboardingInit = async (payload: OnboardingInitPayload) => - await coreApi('/onboarding/init', { +export async function postOnboardingInit(payload: OnboardingInitPayload) { + return await coreApi('/onboarding/init', { method: 'POST', body: payload, }) +} diff --git a/be/apps/dashboard/src/modules/onboarding/components/steps/TenantStep.tsx b/be/apps/dashboard/src/modules/onboarding/components/steps/TenantStep.tsx index 0a52c133..80179dcc 100644 --- a/be/apps/dashboard/src/modules/onboarding/components/steps/TenantStep.tsx +++ b/be/apps/dashboard/src/modules/onboarding/components/steps/TenantStep.tsx @@ -49,7 +49,7 @@ export const TenantStep: FC = ({ tenant, errors, onNameChange, id="tenant-domain" value={tenant.domain} onInput={(event) => onDomainChange(event.currentTarget.value)} - placeholder="gallery.afilmory.app" + placeholder="gallery.afilmory.art" error={!!errors['tenant.domain']} autoComplete="off" /> diff --git a/be/apps/dashboard/src/modules/onboarding/hooks/useOnboardingWizard.ts b/be/apps/dashboard/src/modules/onboarding/hooks/useOnboardingWizard.ts index 1548dae2..77d6ac38 100644 --- a/be/apps/dashboard/src/modules/onboarding/hooks/useOnboardingWizard.ts +++ b/be/apps/dashboard/src/modules/onboarding/hooks/useOnboardingWizard.ts @@ -12,7 +12,7 @@ import { createInitialSettingsState, getFieldByKey, isLikelyEmail, maskSecret, s const INITIAL_STEP_INDEX = 0 -export const useOnboardingWizard = () => { +export function useOnboardingWizard() { const [currentStepIndex, setCurrentStepIndex] = useState(INITIAL_STEP_INDEX) const [tenant, setTenant] = useState({ name: '', diff --git a/be/apps/dashboard/src/modules/onboarding/utils.ts b/be/apps/dashboard/src/modules/onboarding/utils.ts index a9077587..9699a0cd 100644 --- a/be/apps/dashboard/src/modules/onboarding/utils.ts +++ b/be/apps/dashboard/src/modules/onboarding/utils.ts @@ -2,7 +2,7 @@ import type { OnboardingSettingKey, SettingFieldDefinition } from './constants' import { ONBOARDING_SETTING_SECTIONS, ONBOARDING_STEPS } from './constants' import type { SettingFormState } from './types' -export const createInitialSettingsState = (): SettingFormState => { +export function createInitialSettingsState(): SettingFormState { const state = {} as SettingFormState for (const section of ONBOARDING_SETTING_SECTIONS) { for (const field of section.fields) { @@ -14,15 +14,16 @@ export const createInitialSettingsState = (): SettingFormState => { export const maskSecret = (value: string) => (value ? '•'.repeat(Math.min(10, value.length)) : '') -export const slugify = (value: string) => - value +export function slugify(value: string) { + return value .toLowerCase() .trim() .replaceAll(/[^a-z0-9-]+/g, '-') .replaceAll(/-{2,}/g, '-') .replaceAll(/^-+|-+$/g, '') +} -export const isLikelyEmail = (value: string) => { +export function isLikelyEmail(value: string) { const trimmed = value.trim() if (!trimmed.includes('@')) { return false @@ -36,7 +37,7 @@ export const isLikelyEmail = (value: string) => { export const stepProgress = (index: number) => Math.round((index / (ONBOARDING_STEPS.length - 1 || 1)) * 100) -export const getFieldByKey = (key: OnboardingSettingKey): SettingFieldDefinition => { +export function getFieldByKey(key: OnboardingSettingKey): SettingFieldDefinition { for (const section of ONBOARDING_SETTING_SECTIONS) { for (const field of section.fields) { if (field.key === key) { diff --git a/be/apps/dashboard/src/modules/photos/api.ts b/be/apps/dashboard/src/modules/photos/api.ts index 3da5679d..d1cec88d 100644 --- a/be/apps/dashboard/src/modules/photos/api.ts +++ b/be/apps/dashboard/src/modules/photos/api.ts @@ -19,10 +19,10 @@ type RunPhotoSyncOptions = { onEvent?: (event: PhotoSyncProgressEvent) => void } -export const runPhotoSync = async ( +export async function runPhotoSync( payload: RunPhotoSyncPayload, options?: RunPhotoSyncOptions, -): Promise => { +): Promise { const response = await fetch(`${coreApiBaseURL}/data-sync/run`, { method: 'POST', headers: { @@ -134,15 +134,15 @@ export const runPhotoSync = async ( return camelCaseKeys(finalResult) } -export const listPhotoSyncConflicts = async (): Promise => { +export async function listPhotoSyncConflicts(): Promise { const conflicts = await coreApi('/data-sync/conflicts') return camelCaseKeys(conflicts) } -export const resolvePhotoSyncConflict = async ( +export async function resolvePhotoSyncConflict( id: string, payload: { strategy: PhotoSyncResolution; dryRun?: boolean }, -): Promise => { +): Promise { const result = await coreApi(`/data-sync/conflicts/${id}/resolve`, { method: 'POST', body: payload, @@ -151,29 +151,29 @@ export const resolvePhotoSyncConflict = async ( return camelCaseKeys(result) } -export const listPhotoAssets = async (): Promise => { +export async function listPhotoAssets(): Promise { const assets = await coreApi('/photos/assets') return camelCaseKeys(assets) } -export const getPhotoAssetSummary = async (): Promise => { +export async function getPhotoAssetSummary(): Promise { const summary = await coreApi('/photos/assets/summary') return camelCaseKeys(summary) } -export const deletePhotoAssets = async (ids: string[]): Promise => { +export async function deletePhotoAssets(ids: string[]): Promise { await coreApi('/photos/assets', { method: 'DELETE', body: { ids }, }) } -export const uploadPhotoAssets = async ( +export async function uploadPhotoAssets( files: File[], options?: { directory?: string }, -): Promise => { +): Promise { const formData = new FormData() if (options?.directory) { @@ -194,7 +194,7 @@ export const uploadPhotoAssets = async ( return data.assets } -export const getPhotoStorageUrl = async (storageKey: string): Promise => { +export async function getPhotoStorageUrl(storageKey: string): Promise { const result = await coreApi<{ url: string }>('/photos/storage-url', { method: 'GET', query: { key: storageKey }, diff --git a/be/apps/dashboard/src/modules/photos/components/PhotoPage.tsx b/be/apps/dashboard/src/modules/photos/components/PhotoPage.tsx index 2019c38a..b1010070 100644 --- a/be/apps/dashboard/src/modules/photos/components/PhotoPage.tsx +++ b/be/apps/dashboard/src/modules/photos/components/PhotoPage.tsx @@ -40,8 +40,8 @@ const STAGE_ORDER: PhotoSyncProgressStage[] = [ 'status-reconciliation', ] -const createInitialStages = (totals: PhotoSyncProgressState['totals']): PhotoSyncProgressState['stages'] => - STAGE_ORDER.reduce( +function createInitialStages(totals: PhotoSyncProgressState['totals']): PhotoSyncProgressState['stages'] { + return STAGE_ORDER.reduce( (acc, stage) => { const total = totals[stage] acc[stage] = { @@ -53,8 +53,9 @@ const createInitialStages = (totals: PhotoSyncProgressState['totals']): PhotoSyn }, {} as PhotoSyncProgressState['stages'], ) +} -export const PhotoPage = () => { +export function PhotoPage() { const [activeTab, setActiveTab] = useState('sync') const [result, setResult] = useState(null) const [lastWasDryRun, setLastWasDryRun] = useState(null) diff --git a/be/apps/dashboard/src/modules/photos/components/library/Masonry.tsx b/be/apps/dashboard/src/modules/photos/components/library/Masonry.tsx index a426657d..d879b972 100644 --- a/be/apps/dashboard/src/modules/photos/components/library/Masonry.tsx +++ b/be/apps/dashboard/src/modules/photos/components/library/Masonry.tsx @@ -26,7 +26,7 @@ export interface MasonryRef { * * @param props */ -export const Masonry = (props: MasonryProps & { ref?: React.Ref }) => { +export function Masonry(props: MasonryProps & { ref?: React.Ref }) { const [scrollTop, setScrollTop] = React.useState(0) const [isScrolling, setIsScrolling] = React.useState(false) const scrollElement = useScrollViewElement() diff --git a/be/apps/dashboard/src/modules/photos/components/library/PhotoLibraryActionBar.tsx b/be/apps/dashboard/src/modules/photos/components/library/PhotoLibraryActionBar.tsx index 45f4264e..5f3f9c59 100644 --- a/be/apps/dashboard/src/modules/photos/components/library/PhotoLibraryActionBar.tsx +++ b/be/apps/dashboard/src/modules/photos/components/library/PhotoLibraryActionBar.tsx @@ -13,14 +13,14 @@ type PhotoLibraryActionBarProps = { onClearSelection: () => void } -export const PhotoLibraryActionBar = ({ +export function PhotoLibraryActionBar({ selectionCount, isUploading, isDeleting, onUpload, onDeleteSelected, onClearSelection, -}: PhotoLibraryActionBarProps) => { +}: PhotoLibraryActionBarProps) { const fileInputRef = useRef(null) const handleUploadClick = () => { diff --git a/be/apps/dashboard/src/modules/photos/components/library/PhotoLibraryGrid.tsx b/be/apps/dashboard/src/modules/photos/components/library/PhotoLibraryGrid.tsx index dffa212c..e28b3016 100644 --- a/be/apps/dashboard/src/modules/photos/components/library/PhotoLibraryGrid.tsx +++ b/be/apps/dashboard/src/modules/photos/components/library/PhotoLibraryGrid.tsx @@ -15,7 +15,7 @@ type PhotoLibraryGridProps = { isDeleting?: boolean } -const PhotoGridItem = ({ +function PhotoGridItem({ asset, isSelected, onToggleSelect, @@ -29,7 +29,7 @@ const PhotoGridItem = ({ onOpenAsset: (asset: PhotoAssetListItem) => void onDeleteAsset: (asset: PhotoAssetListItem) => Promise | void isDeleting?: boolean -}) => { +}) { const manifest = asset.manifest?.data const previewUrl = manifest?.thumbnailUrl ?? manifest?.originalUrl ?? asset.publicUrl const deviceLabel = manifest?.exif?.Model || manifest?.exif?.Make || '未知设备' @@ -142,7 +142,7 @@ const PhotoGridItem = ({ ) } -export const PhotoLibraryGrid = ({ +export function PhotoLibraryGrid({ assets, isLoading, selectedIds, @@ -150,7 +150,7 @@ export const PhotoLibraryGrid = ({ onOpenAsset, onDeleteAsset, isDeleting, -}: PhotoLibraryGridProps) => { +}: PhotoLibraryGridProps) { if (isLoading) { const skeletonKeys = [ 'photo-skeleton-1', diff --git a/be/apps/dashboard/src/modules/photos/components/sync/PhotoSyncActions.tsx b/be/apps/dashboard/src/modules/photos/components/sync/PhotoSyncActions.tsx index 722ba05f..496e2899 100644 --- a/be/apps/dashboard/src/modules/photos/components/sync/PhotoSyncActions.tsx +++ b/be/apps/dashboard/src/modules/photos/components/sync/PhotoSyncActions.tsx @@ -14,7 +14,7 @@ type PhotoSyncActionsProps = { onError?: (error: Error) => void } -export const PhotoSyncActions = ({ onCompleted, onProgress, onError }: PhotoSyncActionsProps) => { +export function PhotoSyncActions({ onCompleted, onProgress, onError }: PhotoSyncActionsProps) { const { setHeaderActionState } = useMainPageLayout() const [pendingMode, setPendingMode] = useState<'dry-run' | 'apply' | null>(null) const abortRef = useRef(null) diff --git a/be/apps/dashboard/src/modules/photos/components/sync/PhotoSyncConflictsPanel.tsx b/be/apps/dashboard/src/modules/photos/components/sync/PhotoSyncConflictsPanel.tsx index b269a95d..aad7a837 100644 --- a/be/apps/dashboard/src/modules/photos/components/sync/PhotoSyncConflictsPanel.tsx +++ b/be/apps/dashboard/src/modules/photos/components/sync/PhotoSyncConflictsPanel.tsx @@ -18,7 +18,7 @@ type PhotoSyncConflictsPanelProps = { onRequestStorageUrl?: (storageKey: string) => Promise } -const formatDate = (value: string) => { +function formatDate(value: string) { try { return new Date(value).toLocaleString() } catch { @@ -26,7 +26,7 @@ const formatDate = (value: string) => { } } -export const PhotoSyncConflictsPanel = ({ +export function PhotoSyncConflictsPanel({ conflicts, isLoading, resolvingId, @@ -34,7 +34,7 @@ export const PhotoSyncConflictsPanel = ({ onResolve, onResolveBatch, onRequestStorageUrl, -}: PhotoSyncConflictsPanelProps) => { +}: PhotoSyncConflictsPanelProps) { const sortedConflicts = useMemo(() => { if (!conflicts) return [] return conflicts.toSorted((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()) @@ -453,7 +453,7 @@ export const PhotoSyncConflictsPanel = ({ ) } -const ConflictManifestPreview = ({ +function ConflictManifestPreview({ manifest, disabled, onOpenOriginal, @@ -461,7 +461,7 @@ const ConflictManifestPreview = ({ manifest: PhotoSyncConflict['manifest']['data'] | null | undefined disabled?: boolean onOpenOriginal?: () => void -}) => { +}) { if (!manifest) { return (
@@ -511,7 +511,7 @@ const ConflictManifestPreview = ({ ) } -const ConflictStoragePreview = ({ +function ConflictStoragePreview({ storageKey, snapshot, disabled, @@ -521,20 +521,22 @@ const ConflictStoragePreview = ({ snapshot: PhotoSyncSnapshot | null | undefined disabled?: boolean onOpenStorage?: () => void -}) => ( -
-
-

存储对象

- {onOpenStorage ? ( - - ) : null} +}) { + return ( +
+
+

存储对象

+ {onOpenStorage ? ( + + ) : null} +
+

+ Key: + {storageKey} +

+
-

- Key: - {storageKey} -

- -
-) + ) +} diff --git a/be/apps/dashboard/src/modules/photos/components/sync/PhotoSyncProgressPanel.tsx b/be/apps/dashboard/src/modules/photos/components/sync/PhotoSyncProgressPanel.tsx index 38d5e823..d398f2a1 100644 --- a/be/apps/dashboard/src/modules/photos/components/sync/PhotoSyncProgressPanel.tsx +++ b/be/apps/dashboard/src/modules/photos/components/sync/PhotoSyncProgressPanel.tsx @@ -50,7 +50,7 @@ type PhotoSyncProgressPanelProps = { progress: PhotoSyncProgressState } -const formatActionLabel = (action: PhotoSyncAction) => { +function formatActionLabel(action: PhotoSyncAction) { const config = PHOTO_ACTION_TYPE_CONFIG[action.type] if (action.type === 'conflict' && action.conflictPayload) { const conflictLabel = getConflictTypeLabel(action.conflictPayload.type) @@ -60,7 +60,7 @@ const formatActionLabel = (action: PhotoSyncAction) => { return config?.label ?? action.type } -export const PhotoSyncProgressPanel = ({ progress }: PhotoSyncProgressPanelProps) => { +export function PhotoSyncProgressPanel({ progress }: PhotoSyncProgressPanelProps) { const isErrored = Boolean(progress.error) const heading = isErrored ? '同步失败' : progress.dryRun ? '同步预览进行中' : '同步进行中' const subtitle = isErrored diff --git a/be/apps/dashboard/src/modules/photos/components/sync/PhotoSyncResultPanel.tsx b/be/apps/dashboard/src/modules/photos/components/sync/PhotoSyncResultPanel.tsx index 883ac691..cd52e8a7 100644 --- a/be/apps/dashboard/src/modules/photos/components/sync/PhotoSyncResultPanel.tsx +++ b/be/apps/dashboard/src/modules/photos/components/sync/PhotoSyncResultPanel.tsx @@ -6,14 +6,16 @@ import { useMemo, useState } from 'react' import { getConflictTypeLabel, PHOTO_ACTION_TYPE_CONFIG } from '../../constants' import type { PhotoAssetSummary, PhotoSyncAction, PhotoSyncResult, PhotoSyncSnapshot } from '../../types' -export const BorderOverlay = () => ( - <> -
-
-
-
- -) +export function BorderOverlay() { + return ( + <> +
+
+
+
+ + ) +} type SummaryCardProps = { label: string @@ -21,7 +23,7 @@ type SummaryCardProps = { tone?: 'accent' | 'warning' | 'muted' } -const SummaryCard = ({ label, value, tone }: SummaryCardProps) => { +function SummaryCard({ label, value, tone }: SummaryCardProps) { const toneClass = tone === 'accent' ? 'text-accent' @@ -52,13 +54,13 @@ const actionTypeConfig = PHOTO_ACTION_TYPE_CONFIG const SUMMARY_SKELETON_KEYS = ['summary-skeleton-1', 'summary-skeleton-2', 'summary-skeleton-3', 'summary-skeleton-4'] -export const PhotoSyncResultPanel = ({ +export function PhotoSyncResultPanel({ result, lastWasDryRun, baselineSummary, isSummaryLoading, onRequestStorageUrl, -}: PhotoSyncResultPanelProps) => { +}: PhotoSyncResultPanelProps) { const summaryItems = useMemo(() => { if (result) { return [ @@ -439,7 +441,7 @@ export const PhotoSyncResultPanel = ({ ) } -const ManifestPreview = ({ +function ManifestPreview({ title, manifest, onOpenOriginal, @@ -447,7 +449,7 @@ const ManifestPreview = ({ title: string manifest: PhotoSyncAction['manifestAfter'] | PhotoSyncAction['manifestBefore'] onOpenOriginal?: () => void -}) => { +}) { if (!manifest) { return (
@@ -501,7 +503,7 @@ type MetadataSnapshotProps = { snapshot: PhotoSyncSnapshot | null | undefined } -export const MetadataSnapshot = ({ snapshot }: MetadataSnapshotProps) => { +export function MetadataSnapshot({ snapshot }: MetadataSnapshotProps) { if (!snapshot) return null return (
diff --git a/be/apps/dashboard/src/modules/photos/constants.ts b/be/apps/dashboard/src/modules/photos/constants.ts index 9ff86aab..9df0d7db 100644 --- a/be/apps/dashboard/src/modules/photos/constants.ts +++ b/be/apps/dashboard/src/modules/photos/constants.ts @@ -15,7 +15,7 @@ export const PHOTO_CONFLICT_TYPE_CONFIG: Record { +export function getConflictTypeLabel(type: PhotoSyncConflictType | null | undefined): string { if (!type) { return '冲突' } diff --git a/be/apps/dashboard/src/modules/photos/hooks.ts b/be/apps/dashboard/src/modules/photos/hooks.ts index 64f354eb..66576b1a 100644 --- a/be/apps/dashboard/src/modules/photos/hooks.ts +++ b/be/apps/dashboard/src/modules/photos/hooks.ts @@ -14,14 +14,14 @@ export const PHOTO_ASSET_SUMMARY_QUERY_KEY = ['photo-assets', 'summary'] as cons export const PHOTO_ASSET_LIST_QUERY_KEY = ['photo-assets', 'list'] as const export const PHOTO_SYNC_CONFLICTS_QUERY_KEY = ['photo-sync', 'conflicts'] as const -export const usePhotoAssetSummaryQuery = () => { +export function usePhotoAssetSummaryQuery() { return useQuery({ queryKey: PHOTO_ASSET_SUMMARY_QUERY_KEY, queryFn: getPhotoAssetSummary, }) } -export const usePhotoAssetListQuery = (options?: { enabled?: boolean }) => { +export function usePhotoAssetListQuery(options?: { enabled?: boolean }) { return useQuery({ queryKey: PHOTO_ASSET_LIST_QUERY_KEY, queryFn: listPhotoAssets, @@ -29,7 +29,7 @@ export const usePhotoAssetListQuery = (options?: { enabled?: boolean }) => { }) } -export const usePhotoSyncConflictsQuery = (options?: { enabled?: boolean }) => { +export function usePhotoSyncConflictsQuery(options?: { enabled?: boolean }) { return useQuery({ queryKey: PHOTO_SYNC_CONFLICTS_QUERY_KEY, queryFn: listPhotoSyncConflicts, @@ -37,7 +37,7 @@ export const usePhotoSyncConflictsQuery = (options?: { enabled?: boolean }) => { }) } -export const useDeletePhotoAssetsMutation = () => { +export function useDeletePhotoAssetsMutation() { const queryClient = useQueryClient() return useMutation({ @@ -61,7 +61,7 @@ export const useDeletePhotoAssetsMutation = () => { }) } -export const useUploadPhotoAssetsMutation = () => { +export function useUploadPhotoAssetsMutation() { const queryClient = useQueryClient() return useMutation({ @@ -79,7 +79,7 @@ export const useUploadPhotoAssetsMutation = () => { }) } -export const useResolvePhotoSyncConflictMutation = () => { +export function useResolvePhotoSyncConflictMutation() { const queryClient = useQueryClient() return useMutation({ diff --git a/be/apps/dashboard/src/modules/schema-form/SchemaFormRenderer.tsx b/be/apps/dashboard/src/modules/schema-form/SchemaFormRenderer.tsx index f2e42200..319e1346 100644 --- a/be/apps/dashboard/src/modules/schema-form/SchemaFormRenderer.tsx +++ b/be/apps/dashboard/src/modules/schema-form/SchemaFormRenderer.tsx @@ -16,6 +16,7 @@ import { DynamicIcon } from 'lucide-react/dynamic' import type { ReactNode } from 'react' import { Fragment, useState } from 'react' +import { LinearBorderPanel } from '../../components/common/GlassPanel' import type { SchemaFormState, SchemaFormValue, @@ -27,19 +28,7 @@ import type { UiSlotComponent, } from './types' -export const GlassPanel = ({ className, children }: { className?: string; children: ReactNode }) => ( -
- {/* Linear gradient borders - sharp edges */} -
-
-
-
- -
{children}
-
-) - -const FieldDescription = ({ description }: { description?: string | null }) => { +function FieldDescription({ description }: { description?: string | null }) { if (!description) { return null } @@ -47,7 +36,7 @@ const FieldDescription = ({ description }: { description?: string | null }) => { return

{description}

} -const SchemaIcon = ({ name, className }: { name?: string | null; className?: string }) => { +function SchemaIcon({ name, className }: { name?: string | null; className?: string }) { if (!name) { return null } @@ -55,7 +44,7 @@ const SchemaIcon = ({ name, className }: { name?: string | null; className?: str return } -const SecretFieldInput = ({ +function SecretFieldInput({ component, fieldKey, value, @@ -65,7 +54,7 @@ const SecretFieldInput = ({ fieldKey: Key value: string onChange: (key: Key, value: SchemaFormValue) => void -}) => { +}) { const [revealed, setRevealed] = useState(false) return ( @@ -107,13 +96,7 @@ type FieldRendererProps = { context: SchemaRendererContext } -const FieldRenderer = ({ - field, - value, - onChange, - renderSlot, - context, -}: FieldRendererProps) => { +function FieldRenderer({ field, value, onChange, renderSlot, context }: FieldRendererProps) { const { component } = field if (component.type === 'slot') { @@ -184,14 +167,14 @@ const FieldRenderer = ({ ) } -const renderGroup = ( +function renderGroup( node: UiGroupNode, context: SchemaRendererContext, formState: SchemaFormState, handleChange: (key: Key, value: SchemaFormValue) => void, shouldRenderNode?: SchemaFormRendererProps['shouldRenderNode'], renderSlot?: SlotRenderer, -) => { +) { const renderedChildren = node.children .map((child) => renderNode(child, context, formState, handleChange, shouldRenderNode, renderSlot)) .filter(Boolean) @@ -219,13 +202,13 @@ const renderGroup = ( ) } -const renderField = ( +function renderField( field: UiFieldNode, formState: SchemaFormState, handleChange: (key: Key, value: SchemaFormValue) => void, renderSlot: SlotRenderer | undefined, context: SchemaRendererContext, -) => { +) { if (field.hidden) { return null } @@ -237,7 +220,7 @@ const renderField = ( const helper = helperText ? {helperText} : null return ( -
+
@@ -259,7 +242,7 @@ const renderField = ( const showSensitiveHint = isSensitive && typeof value === 'string' && value.length === 0 return ( -
+
@@ -277,14 +260,14 @@ const renderField = ( ) } -const renderNode = ( +function renderNode( node: UiNode, context: SchemaRendererContext, formState: SchemaFormState, handleChange: (key: Key, value: SchemaFormValue) => void, shouldRenderNode?: SchemaFormRendererProps['shouldRenderNode'], renderSlot?: SlotRenderer, -): ReactNode => { +): ReactNode { if (shouldRenderNode && !shouldRenderNode(node, context)) { return null } @@ -329,13 +312,13 @@ export interface SchemaFormRendererProps { renderSlot?: SlotRenderer } -export const SchemaFormRenderer = ({ +export function SchemaFormRenderer({ schema, values, onChange, shouldRenderNode, renderSlot, -}: SchemaFormRendererProps) => { +}: SchemaFormRendererProps) { const context: SchemaRendererContext = { values } return ( @@ -354,7 +337,7 @@ export const SchemaFormRenderer = ({ } return ( - +
@@ -366,7 +349,7 @@ export const SchemaFormRenderer = ({
{renderedChildren}
- + ) })} diff --git a/be/apps/dashboard/src/modules/schema-form/types.ts b/be/apps/dashboard/src/modules/schema-form/types.ts index d8ca5e20..d24cf8b9 100644 --- a/be/apps/dashboard/src/modules/schema-form/types.ts +++ b/be/apps/dashboard/src/modules/schema-form/types.ts @@ -24,7 +24,7 @@ export interface UiTextareaComponent extends UiFieldComponentBase<'textarea'> { export interface UiSelectComponent extends UiFieldComponentBase<'select'> { readonly placeholder?: string - readonly options?: ReadonlyArray + readonly options?: readonly string[] readonly allowCustom?: boolean } diff --git a/be/apps/dashboard/src/modules/schema-form/utils.ts b/be/apps/dashboard/src/modules/schema-form/utils.ts index b1fb7da3..16efa741 100644 --- a/be/apps/dashboard/src/modules/schema-form/utils.ts +++ b/be/apps/dashboard/src/modules/schema-form/utils.ts @@ -1,7 +1,7 @@ import type { UiFieldNode, UiNode } from './types' -export const collectFieldNodes = (nodes: ReadonlyArray>): UiFieldNode[] => { - const fields: UiFieldNode[] = [] +export function collectFieldNodes(nodes: ReadonlyArray>): Array> { + const fields: Array> = [] for (const node of nodes) { if (node.type === 'field') { diff --git a/be/apps/dashboard/src/modules/settings/api.ts b/be/apps/dashboard/src/modules/settings/api.ts index f11a307a..348d5baf 100644 --- a/be/apps/dashboard/src/modules/settings/api.ts +++ b/be/apps/dashboard/src/modules/settings/api.ts @@ -2,11 +2,11 @@ import { coreApi } from '~/lib/api-client' import type { SettingEntryInput, SettingUiSchemaResponse } from './types' -export const getSettingUiSchema = async () => { +export async function getSettingUiSchema() { return await coreApi('/settings/ui-schema') } -export const getSettings = async (keys: ReadonlyArray) => { +export async function getSettings(keys: readonly string[]) { return await coreApi<{ keys: string[] values: Record @@ -16,8 +16,8 @@ export const getSettings = async (keys: ReadonlyArray) => { }) } -export const updateSettings = async (entries: ReadonlyArray) => { - return await coreApi<{ updated: ReadonlyArray }>('/settings', { +export async function updateSettings(entries: readonly SettingEntryInput[]) { + return await coreApi<{ updated: readonly SettingEntryInput[] }>('/settings', { method: 'POST', body: { entries }, }) diff --git a/be/apps/dashboard/src/modules/settings/components/SettingsForm.tsx b/be/apps/dashboard/src/modules/settings/components/SettingsForm.tsx index 4e3f717f..e9f7cfca 100644 --- a/be/apps/dashboard/src/modules/settings/components/SettingsForm.tsx +++ b/be/apps/dashboard/src/modules/settings/components/SettingsForm.tsx @@ -3,10 +3,11 @@ import { Spring } from '@afilmory/utils' import { m } from 'motion/react' import { startTransition, useCallback, useEffect, useId, useMemo, useState } from 'react' +import { LinearBorderPanel } from '~/components/common/GlassPanel' import { MainPageLayout, useMainPageLayout } from '~/components/layouts/MainPageLayout' import type { SchemaFormRendererProps } from '../../schema-form/SchemaFormRenderer' -import { GlassPanel, SchemaFormRenderer } from '../../schema-form/SchemaFormRenderer' +import { SchemaFormRenderer } from '../../schema-form/SchemaFormRenderer' import type { SchemaFormValue } from '../../schema-form/types' import { collectFieldNodes } from '../../schema-form/utils' import { useSettingUiSchemaQuery, useUpdateSettingsMutation } from '../hooks' @@ -19,10 +20,10 @@ const providerGroupVisibility: Record = { 'builder-storage-eagle': 'eagle', } -const buildInitialState = ( +function buildInitialState( schema: SettingUiSchemaResponse['schema'], values: SettingUiSchemaResponse['values'], -): SettingValueState => { +): SettingValueState { const state: SettingValueState = {} as SettingValueState const fields = collectFieldNodes(schema.sections) @@ -34,7 +35,7 @@ const buildInitialState = ( return state } -export const SettingsForm = () => { +export function SettingsForm() { const { data, isLoading, isError, error } = useSettingUiSchemaQuery() const updateSettingsMutation = useUpdateSettingsMutation() const { setHeaderActionState } = useMainPageLayout() @@ -145,7 +146,7 @@ export const SettingsForm = () => { return ( <> {headerActionPortal} - +
@@ -154,7 +155,7 @@ export const SettingsForm = () => { ))}
- + ) } @@ -163,12 +164,12 @@ export const SettingsForm = () => { return ( <> {headerActionPortal} - +
{`无法加载设置:${error instanceof Error ? error.message : '未知错误'}`}
-
+ ) } diff --git a/be/apps/dashboard/src/modules/settings/components/SettingsNavigation.tsx b/be/apps/dashboard/src/modules/settings/components/SettingsNavigation.tsx index e27c59f3..1d06bd4a 100644 --- a/be/apps/dashboard/src/modules/settings/components/SettingsNavigation.tsx +++ b/be/apps/dashboard/src/modules/settings/components/SettingsNavigation.tsx @@ -19,7 +19,7 @@ type SettingsNavigationProps = { active: (typeof SETTINGS_TABS)[number]['id'] } -export const SettingsNavigation = ({ active }: SettingsNavigationProps) => { +export function SettingsNavigation({ active }: SettingsNavigationProps) { return ( { +export function useSettingUiSchemaQuery() { return useQuery({ queryKey: SETTING_UI_SCHEMA_QUERY_KEY, queryFn: getSettingUiSchema, }) } -export const useUpdateSettingsMutation = () => { +export function useUpdateSettingsMutation() { const queryClient = useQueryClient() return useMutation({ - mutationFn: async (entries: ReadonlyArray) => { + mutationFn: async (entries: readonly SettingEntryInput[]) => { await updateSettings(entries) }, onSuccess: () => { diff --git a/be/apps/dashboard/src/modules/storage-providers/components/ProviderEditModal.tsx b/be/apps/dashboard/src/modules/storage-providers/components/ProviderEditModal.tsx index 51f64d32..d7a3ef9e 100644 --- a/be/apps/dashboard/src/modules/storage-providers/components/ProviderEditModal.tsx +++ b/be/apps/dashboard/src/modules/storage-providers/components/ProviderEditModal.tsx @@ -29,13 +29,13 @@ type ProviderEditModalProps = ModalComponentProps & { onSetActive: (id: string) => void } -export const ProviderEditModal = ({ +export function ProviderEditModal({ provider, onSave, dismiss, -}: ProviderEditModalProps) => { +}: ProviderEditModalProps) { const [formData, setFormData] = useState(provider) const [isDirty, setIsDirty] = useState(false) diff --git a/be/apps/dashboard/src/modules/storage-providers/components/StorageProvidersManager.tsx b/be/apps/dashboard/src/modules/storage-providers/components/StorageProvidersManager.tsx index f4765f90..81719e4d 100644 --- a/be/apps/dashboard/src/modules/storage-providers/components/StorageProvidersManager.tsx +++ b/be/apps/dashboard/src/modules/storage-providers/components/StorageProvidersManager.tsx @@ -12,7 +12,7 @@ import { createEmptyProvider, reorderProvidersByActive } from '../utils' import { ProviderCard } from './ProviderCard' import { ProviderEditModal } from './ProviderEditModal' -export const StorageProvidersManager = () => { +export function StorageProvidersManager() { const { data, isLoading, isError, error } = useStorageProvidersQuery() const updateMutation = useUpdateStorageProvidersMutation() const { setHeaderActionState } = useMainPageLayout() diff --git a/be/apps/dashboard/src/modules/storage-providers/constants.ts b/be/apps/dashboard/src/modules/storage-providers/constants.ts index f6c66871..09361778 100644 --- a/be/apps/dashboard/src/modules/storage-providers/constants.ts +++ b/be/apps/dashboard/src/modules/storage-providers/constants.ts @@ -19,7 +19,7 @@ export const STORAGE_PROVIDER_TYPE_OPTIONS: ReadonlyArray<{ export const STORAGE_PROVIDER_FIELD_DEFINITIONS: Record< StorageProviderType, - ReadonlyArray + readonly StorageProviderFieldDefinition[] > = { s3: [ { diff --git a/be/apps/dashboard/src/modules/storage-providers/hooks.ts b/be/apps/dashboard/src/modules/storage-providers/hooks.ts index 6fe478b2..cc22f350 100644 --- a/be/apps/dashboard/src/modules/storage-providers/hooks.ts +++ b/be/apps/dashboard/src/modules/storage-providers/hooks.ts @@ -13,7 +13,7 @@ import { export const STORAGE_PROVIDERS_QUERY_KEY = ['settings', 'storage-providers'] as const -export const useStorageProvidersQuery = () => { +export function useStorageProvidersQuery() { return useQuery({ queryKey: STORAGE_PROVIDERS_QUERY_KEY, queryFn: async () => { @@ -33,7 +33,7 @@ export const useStorageProvidersQuery = () => { }) } -export const useUpdateStorageProvidersMutation = () => { +export function useUpdateStorageProvidersMutation() { const queryClient = useQueryClient() return useMutation({ @@ -65,10 +65,10 @@ export const useUpdateStorageProvidersMutation = () => { }) } -const restoreProviderSecrets = ( +function restoreProviderSecrets( nextProviders: StorageProvider[], previousProviders: StorageProvider[], -): StorageProvider[] => { +): StorageProvider[] { const previousMap = new Map(previousProviders.map((provider) => [provider.id, provider])) return nextProviders.map((provider) => { diff --git a/be/apps/dashboard/src/modules/storage-providers/utils.ts b/be/apps/dashboard/src/modules/storage-providers/utils.ts index 29d040d6..569febf3 100644 --- a/be/apps/dashboard/src/modules/storage-providers/utils.ts +++ b/be/apps/dashboard/src/modules/storage-providers/utils.ts @@ -1,18 +1,18 @@ import { STORAGE_PROVIDER_FIELD_DEFINITIONS, STORAGE_PROVIDER_TYPES } from './constants' import type { StorageProvider, StorageProviderType } from './types' -const generateId = () => { +function generateId() { if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') { return crypto.randomUUID() } return Math.random().toString(36).slice(2, 10) } -export const isStorageProviderType = (value: unknown): value is StorageProviderType => { +export function isStorageProviderType(value: unknown): value is StorageProviderType { return STORAGE_PROVIDER_TYPES.includes(value as StorageProviderType) } -const normaliseConfigForType = (type: StorageProviderType, config: Record): Record => { +function normaliseConfigForType(type: StorageProviderType, config: Record): Record { return STORAGE_PROVIDER_FIELD_DEFINITIONS[type].reduce>((acc, field) => { const raw = config[field.key] acc[field.key] = typeof raw === 'string' ? raw : raw == null ? '' : String(raw) @@ -20,7 +20,7 @@ const normaliseConfigForType = (type: StorageProviderType, config: Record { +function coerceProvider(input: unknown): StorageProvider | null { if (!input || typeof input !== 'object' || Array.isArray(input)) { return null } @@ -50,7 +50,7 @@ const coerceProvider = (input: unknown): StorageProvider | null => { return provider } -export const parseStorageProviders = (raw: string | null): StorageProvider[] => { +export function parseStorageProviders(raw: string | null): StorageProvider[] { if (!raw) { return [] } @@ -67,7 +67,7 @@ export const parseStorageProviders = (raw: string | null): StorageProvider[] => } } -export const serializeStorageProviders = (providers: ReadonlyArray): string => { +export function serializeStorageProviders(providers: readonly StorageProvider[]): string { return JSON.stringify( providers.map((provider) => ({ ...provider, @@ -76,21 +76,21 @@ export const serializeStorageProviders = (providers: ReadonlyArray { +export function normalizeStorageProviderConfig(provider: StorageProvider): StorageProvider { return { ...provider, config: normaliseConfigForType(provider.type, provider.config), } } -export const getDefaultConfigForType = (type: StorageProviderType): Record => { +export function getDefaultConfigForType(type: StorageProviderType): Record { return STORAGE_PROVIDER_FIELD_DEFINITIONS[type].reduce>((acc, field) => { acc[field.key] = '' return acc }, {}) } -export const createEmptyProvider = (type: StorageProviderType): StorageProvider => { +export function createEmptyProvider(type: StorageProviderType): StorageProvider { const timestamp = new Date().toISOString() return { id: '', @@ -102,10 +102,7 @@ export const createEmptyProvider = (type: StorageProviderType): StorageProvider } } -export const ensureActiveProviderId = ( - providers: ReadonlyArray, - activeId: string | null, -): string | null => { +export function ensureActiveProviderId(providers: readonly StorageProvider[], activeId: string | null): string | null { if (!activeId) { return null } @@ -113,10 +110,10 @@ export const ensureActiveProviderId = ( return providers.some((provider) => provider.id === activeId) ? activeId : null } -export const reorderProvidersByActive = ( - providers: ReadonlyArray, +export function reorderProvidersByActive( + providers: readonly StorageProvider[], activeId: string | null, -): StorageProvider[] => { +): StorageProvider[] { if (!activeId) { return [...providers] } diff --git a/be/apps/dashboard/src/modules/super-admin/api.ts b/be/apps/dashboard/src/modules/super-admin/api.ts index 79abac55..0c82f178 100644 --- a/be/apps/dashboard/src/modules/super-admin/api.ts +++ b/be/apps/dashboard/src/modules/super-admin/api.ts @@ -4,12 +4,13 @@ import type { SuperAdminSettingsResponse, UpdateSuperAdminSettingsPayload } from const SUPER_ADMIN_SETTINGS_ENDPOINT = '/super-admin/settings' -export const fetchSuperAdminSettings = async () => - await coreApi(`${SUPER_ADMIN_SETTINGS_ENDPOINT}`, { +export async function fetchSuperAdminSettings() { + return await coreApi(`${SUPER_ADMIN_SETTINGS_ENDPOINT}`, { method: 'GET', }) +} -export const updateSuperAdminSettings = async (payload: UpdateSuperAdminSettingsPayload) => { +export async function updateSuperAdminSettings(payload: UpdateSuperAdminSettingsPayload) { const sanitizedEntries = Object.entries(payload).filter(([, value]) => value !== undefined) const body = Object.fromEntries(sanitizedEntries) diff --git a/be/apps/dashboard/src/modules/super-admin/components/SuperAdminSettingsForm.tsx b/be/apps/dashboard/src/modules/super-admin/components/SuperAdminSettingsForm.tsx index 078bafa5..a264a259 100644 --- a/be/apps/dashboard/src/modules/super-admin/components/SuperAdminSettingsForm.tsx +++ b/be/apps/dashboard/src/modules/super-admin/components/SuperAdminSettingsForm.tsx @@ -3,7 +3,9 @@ import { Spring } from '@afilmory/utils' import { m } from 'motion/react' import { startTransition, useCallback, useEffect, useMemo, useRef, useState } from 'react' -import { GlassPanel, SchemaFormRenderer } from '../../schema-form/SchemaFormRenderer' +import { LinearBorderPanel } from '~/components/common/GlassPanel' + +import { SchemaFormRenderer } from '../../schema-form/SchemaFormRenderer' import type { SchemaFormValue } from '../../schema-form/types' import { useSuperAdminSettingsQuery, useUpdateSuperAdminSettingsMutation } from '../hooks' import type { @@ -17,13 +19,15 @@ type FormState = Record const BOOLEAN_FIELDS = new Set(['allowRegistration', 'localProviderEnabled']) -const toFormState = (settings: SuperAdminSettings): FormState => ({ - allowRegistration: settings.allowRegistration, - localProviderEnabled: settings.localProviderEnabled, - maxRegistrableUsers: settings.maxRegistrableUsers === null ? '' : String(settings.maxRegistrableUsers), -}) +function toFormState(settings: SuperAdminSettings): FormState { + return { + allowRegistration: settings.allowRegistration, + localProviderEnabled: settings.localProviderEnabled, + maxRegistrableUsers: settings.maxRegistrableUsers === null ? '' : String(settings.maxRegistrableUsers), + } +} -const areFormStatesEqual = (left: FormState | null, right: FormState | null): boolean => { +function areFormStatesEqual(left: FormState | null, right: FormState | null): boolean { if (left === right) { return true } @@ -39,7 +43,7 @@ const areFormStatesEqual = (left: FormState | null, right: FormState | null): bo ) } -const normalizeMaxUsers = (value: SchemaFormValue): string => { +function normalizeMaxUsers(value: SchemaFormValue): string { if (typeof value === 'string') { return value } @@ -59,7 +63,7 @@ type PossiblySnakeCaseSettings = Partial< } > -const coerceMaxUsers = (value: unknown): number | null => { +function coerceMaxUsers(value: unknown): number | null { if (value === undefined || value === null) { return null } @@ -72,7 +76,7 @@ const coerceMaxUsers = (value: unknown): number | null => { return Number.isFinite(parsed) ? parsed : null } -const normalizeServerSettings = (input: PossiblySnakeCaseSettings | null): SuperAdminSettings | null => { +function normalizeServerSettings(input: PossiblySnakeCaseSettings | null): SuperAdminSettings | null { if (!input) { return null } @@ -96,7 +100,7 @@ const normalizeServerSettings = (input: PossiblySnakeCaseSettings | null): Super return null } -const extractServerValues = (payload: SuperAdminSettingsResponse): SuperAdminSettings | null => { +function extractServerValues(payload: SuperAdminSettingsResponse): SuperAdminSettings | null { if ('values' in payload) { return normalizeServerSettings(payload.values ?? null) } @@ -108,7 +112,7 @@ const extractServerValues = (payload: SuperAdminSettingsResponse): SuperAdminSet return null } -export const SuperAdminSettingsForm = () => { +export function SuperAdminSettingsForm() { const { data, isLoading, isError, error } = useSuperAdminSettingsQuery() const [formState, setFormState] = useState(null) const [initialState, setInitialState] = useState(null) @@ -244,24 +248,24 @@ export const SuperAdminSettingsForm = () => { if (isError) { return ( - +
{`无法加载超级管理员设置:${error instanceof Error ? error.message : '未知错误'}`}
-
+ ) } if (isLoading || !formState || !data) { return ( - +
{['skeleton-1', 'skeleton-2', 'skeleton-3'].map((key) => (
))}
- + ) } @@ -290,18 +294,18 @@ export const SuperAdminSettingsForm = () => {
- +

当前用户总数

{typeof totalUsers === 'number' ? totalUsers : 0}

-
- + +

剩余可注册名额

{remainingLabel}

-
+
diff --git a/be/apps/dashboard/src/modules/super-admin/hooks.ts b/be/apps/dashboard/src/modules/super-admin/hooks.ts index dd334a4c..8bb73310 100644 --- a/be/apps/dashboard/src/modules/super-admin/hooks.ts +++ b/be/apps/dashboard/src/modules/super-admin/hooks.ts @@ -5,18 +5,19 @@ import type { SuperAdminSettingsResponse, UpdateSuperAdminSettingsPayload } from export const SUPER_ADMIN_SETTINGS_QUERY_KEY = ['super-admin', 'settings'] as const -export const useSuperAdminSettingsQuery = () => - useQuery({ +export function useSuperAdminSettingsQuery() { + return useQuery({ queryKey: SUPER_ADMIN_SETTINGS_QUERY_KEY, queryFn: fetchSuperAdminSettings, staleTime: 60 * 1000, }) +} type SuperAdminSettingsMutationOptions = { onSuccess?: (data: SuperAdminSettingsResponse) => void } -export const useUpdateSuperAdminSettingsMutation = (options?: SuperAdminSettingsMutationOptions) => { +export function useUpdateSuperAdminSettingsMutation(options?: SuperAdminSettingsMutationOptions) { const queryClient = useQueryClient() return useMutation({ diff --git a/be/apps/dashboard/src/pages/(main)/analytics.tsx b/be/apps/dashboard/src/pages/(main)/analytics.tsx index b89fb06d..381f8406 100644 --- a/be/apps/dashboard/src/pages/(main)/analytics.tsx +++ b/be/apps/dashboard/src/pages/(main)/analytics.tsx @@ -1,6 +1,6 @@ import { MainPageLayout } from '~/components/layouts/MainPageLayout' -export const Component = () => { +export function Component() { return (
diff --git a/be/apps/dashboard/src/pages/(main)/index.tsx b/be/apps/dashboard/src/pages/(main)/index.tsx index ba61a6c5..3eda8b14 100644 --- a/be/apps/dashboard/src/pages/(main)/index.tsx +++ b/be/apps/dashboard/src/pages/(main)/index.tsx @@ -1,68 +1,3 @@ -import { Spring } from '@afilmory/utils' -import { m } from 'motion/react' +import { DashboardOverview } from '~/modules/dashboard/components/DashboardOverview' -import { MainPageLayout } from '~/components/layouts/MainPageLayout' - -export const Component = () => { - return ( - -
- {/* Stats Cards - Sharp Edges */} -
- {[ - { label: 'Total Photos', value: '1,234', trend: '+12%' }, - { label: 'Storage Used', value: '45.2 GB', trend: '+8%' }, - { label: 'This Month', value: '156', trend: '+24%' }, - ].map((stat, index) => ( - - {/* Gradient borders */} -
-
-
-
- -
{stat.label}
-
{stat.value}
-
{stat.trend} from last month
- - ))} -
- - {/* Recent Activity - Sharp Edges */} -
- {/* Gradient borders */} -
-
-
-
- -

Recent Activity

-
- {[ - { action: 'Uploaded 23 photos', time: '2 hours ago' }, - { - action: 'Created new album "Summer 2024"', - time: '5 hours ago', - }, - { action: 'Shared album with 3 people', time: '1 day ago' }, - ].map((activity) => ( -
- {activity.action} - {activity.time} -
- ))} -
-
-
- - ) -} +export const Component = () => diff --git a/be/apps/dashboard/src/pages/(main)/layout.tsx b/be/apps/dashboard/src/pages/(main)/layout.tsx index 344b3536..e3af0e7e 100644 --- a/be/apps/dashboard/src/pages/(main)/layout.tsx +++ b/be/apps/dashboard/src/pages/(main)/layout.tsx @@ -13,7 +13,7 @@ const navigationTabs = [ { label: 'Analytics', path: '/analytics' }, ] as const -export const Component = () => { +export function Component() { const { logout } = usePageRedirect() const user = useAuthUserValue() const [isLoggingOut, setIsLoggingOut] = useState(false) diff --git a/be/apps/dashboard/src/pages/(main)/photos.tsx b/be/apps/dashboard/src/pages/(main)/photos.tsx index 0618cd1b..6b9dd6f4 100644 --- a/be/apps/dashboard/src/pages/(main)/photos.tsx +++ b/be/apps/dashboard/src/pages/(main)/photos.tsx @@ -1,5 +1,5 @@ import { PhotoPage } from '~/modules/photos' -export const Component = () => { +export function Component() { return } diff --git a/be/apps/dashboard/src/pages/(main)/settings/index.tsx b/be/apps/dashboard/src/pages/(main)/settings/index.tsx index 7b66ae9a..78e273a7 100644 --- a/be/apps/dashboard/src/pages/(main)/settings/index.tsx +++ b/be/apps/dashboard/src/pages/(main)/settings/index.tsx @@ -1,7 +1,7 @@ import { MainPageLayout } from '~/components/layouts/MainPageLayout' import { SettingsForm, SettingsNavigation } from '~/modules/settings' -export const Component = () => { +export function Component() { return (
diff --git a/be/apps/dashboard/src/pages/(main)/settings/storage.tsx b/be/apps/dashboard/src/pages/(main)/settings/storage.tsx index 92ffe7c5..5c676d6a 100644 --- a/be/apps/dashboard/src/pages/(main)/settings/storage.tsx +++ b/be/apps/dashboard/src/pages/(main)/settings/storage.tsx @@ -2,7 +2,7 @@ import { MainPageLayout } from '~/components/layouts/MainPageLayout' import { SettingsNavigation } from '~/modules/settings' import { StorageProvidersManager } from '~/modules/storage-providers' -export const Component = () => { +export function Component() { return ( { +export function Component() { const [email, setEmail] = useState('') const [password, setPassword] = useState('') const { login, isLoading, error, clearError } = useLogin() diff --git a/be/apps/dashboard/src/pages/superadmin/index.tsx b/be/apps/dashboard/src/pages/superadmin/index.tsx index 65662c28..c8c8622a 100644 --- a/be/apps/dashboard/src/pages/superadmin/index.tsx +++ b/be/apps/dashboard/src/pages/superadmin/index.tsx @@ -1,5 +1,5 @@ import { Navigate } from 'react-router' -export const Component = () => { +export function Component() { return } diff --git a/be/apps/dashboard/src/pages/superadmin/layout.tsx b/be/apps/dashboard/src/pages/superadmin/layout.tsx index 39dac64d..bbee28d8 100644 --- a/be/apps/dashboard/src/pages/superadmin/layout.tsx +++ b/be/apps/dashboard/src/pages/superadmin/layout.tsx @@ -9,7 +9,7 @@ import { usePageRedirect } from '~/hooks/usePageRedirect' const navigationTabs = [{ label: '系统设置', path: '/superadmin/settings' }] as const -export const Component = () => { +export function Component() { const { logout } = usePageRedirect() const user = useAuthUserValue() const isSuperAdmin = useIsSuperAdmin() diff --git a/be/apps/dashboard/src/pages/superadmin/settings.tsx b/be/apps/dashboard/src/pages/superadmin/settings.tsx index ad60dd33..cbff38f2 100644 --- a/be/apps/dashboard/src/pages/superadmin/settings.tsx +++ b/be/apps/dashboard/src/pages/superadmin/settings.tsx @@ -3,7 +3,7 @@ import { m } from 'motion/react' import { SuperAdminSettingsForm } from '~/modules/super-admin' -export const Component = () => { +export function Component() { return ( ( ) -const Handler = () => { +function Handler() { const ref = useRef(null) const [contextMenuState, setContextMenuState] = useContextMenuState() diff --git a/be/apps/dashboard/src/providers/stable-router-provider.tsx b/be/apps/dashboard/src/providers/stable-router-provider.tsx index ed74800f..424c4b84 100644 --- a/be/apps/dashboard/src/providers/stable-router-provider.tsx +++ b/be/apps/dashboard/src/providers/stable-router-provider.tsx @@ -23,7 +23,7 @@ window.router = { * And use our router hooks will not re-render the component when the router has any changes. * Also it can access values outside of the component and provide a value selector */ -export const StableRouterProvider = () => { +export function StableRouterProvider() { const [searchParams] = useSearchParams() const params = useParams() const nav = useNavigate() diff --git a/be/packages/db/migrations/0003_lovely_wendell_rand.sql b/be/packages/db/migrations/0003_lovely_wendell_rand.sql new file mode 100644 index 00000000..28b93d6d --- /dev/null +++ b/be/packages/db/migrations/0003_lovely_wendell_rand.sql @@ -0,0 +1,9 @@ +CREATE TABLE "reactions" ( + "id" text PRIMARY KEY NOT NULL, + "tenant_id" text NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "ref_key" text NOT NULL, + "reaction" text NOT NULL +); +--> statement-breakpoint +ALTER TABLE "reactions" ADD CONSTRAINT "reactions_tenant_id_tenant_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenant"("id") ON DELETE cascade ON UPDATE no action; \ No newline at end of file diff --git a/be/packages/db/migrations/meta/0003_snapshot.json b/be/packages/db/migrations/meta/0003_snapshot.json new file mode 100644 index 00000000..d519c4fd --- /dev/null +++ b/be/packages/db/migrations/meta/0003_snapshot.json @@ -0,0 +1,834 @@ +{ + "id": "73c602e7-efc2-46a3-ab83-cecf071c2035", + "prevId": "40bebd58-4e8e-4961-aca6-df9bf5f091e3", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.auth_account": { + "name": "auth_account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token_expires_at": { + "name": "access_token_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "refresh_token_expires_at": { + "name": "refresh_token_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "auth_account_user_id_auth_user_id_fk": { + "name": "auth_account_user_id_auth_user_id_fk", + "tableFrom": "auth_account", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_session": { + "name": "auth_session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "tenant_id": { + "name": "tenant_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "auth_session_tenant_id_tenant_id_fk": { + "name": "auth_session_tenant_id_tenant_id_fk", + "tableFrom": "auth_session", + "tableTo": "tenant", + "columnsFrom": ["tenant_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + }, + "auth_session_user_id_auth_user_id_fk": { + "name": "auth_session_user_id_auth_user_id_fk", + "tableFrom": "auth_session", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "auth_session_token_unique": { + "name": "auth_session_token_unique", + "nullsNotDistinct": false, + "columns": ["token"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_user": { + "name": "auth_user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "role": { + "name": "role", + "type": "user_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'user'" + }, + "tenant_id": { + "name": "tenant_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "two_factor_enabled": { + "name": "two_factor_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "display_username": { + "name": "display_username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "banned": { + "name": "banned", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "ban_reason": { + "name": "ban_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ban_expires_at": { + "name": "ban_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "auth_user_tenant_id_tenant_id_fk": { + "name": "auth_user_tenant_id_tenant_id_fk", + "tableFrom": "auth_user", + "tableTo": "tenant", + "columnsFrom": ["tenant_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "auth_user_email_unique": { + "name": "auth_user_email_unique", + "nullsNotDistinct": false, + "columns": ["email"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.photo_asset": { + "name": "photo_asset", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "tenant_id": { + "name": "tenant_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "photo_id": { + "name": "photo_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "storage_provider": { + "name": "storage_provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "size": { + "name": "size", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "etag": { + "name": "etag", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "metadata_hash": { + "name": "metadata_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "manifest_version": { + "name": "manifest_version", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'v7'" + }, + "manifest": { + "name": "manifest", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "sync_status": { + "name": "sync_status", + "type": "photo_sync_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "conflict_reason": { + "name": "conflict_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "conflict_payload": { + "name": "conflict_payload", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'null'::jsonb" + }, + "synced_at": { + "name": "synced_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "photo_asset_tenant_id_tenant_id_fk": { + "name": "photo_asset_tenant_id_tenant_id_fk", + "tableFrom": "photo_asset", + "tableTo": "tenant", + "columnsFrom": ["tenant_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "uq_photo_asset_tenant_storage_key": { + "name": "uq_photo_asset_tenant_storage_key", + "nullsNotDistinct": false, + "columns": ["tenant_id", "storage_key"] + }, + "uq_photo_asset_tenant_photo_id": { + "name": "uq_photo_asset_tenant_photo_id", + "nullsNotDistinct": false, + "columns": ["tenant_id", "photo_id"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.reactions": { + "name": "reactions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "tenant_id": { + "name": "tenant_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "ref_key": { + "name": "ref_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reaction": { + "name": "reaction", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "reactions_tenant_id_tenant_id_fk": { + "name": "reactions_tenant_id_tenant_id_fk", + "tableFrom": "reactions", + "tableTo": "tenant", + "columnsFrom": ["tenant_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.settings": { + "name": "settings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "tenant_id": { + "name": "tenant_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_sensitive": { + "name": "is_sensitive", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "settings_tenant_id_tenant_id_fk": { + "name": "settings_tenant_id_tenant_id_fk", + "tableFrom": "settings", + "tableTo": "tenant", + "columnsFrom": ["tenant_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "uq_settings_tenant_key": { + "name": "uq_settings_tenant_key", + "nullsNotDistinct": false, + "columns": ["tenant_id", "key"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.system_setting": { + "name": "system_setting", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'null'::jsonb" + }, + "is_sensitive": { + "name": "is_sensitive", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "uq_system_setting_key": { + "name": "uq_system_setting_key", + "nullsNotDistinct": false, + "columns": ["key"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.tenant_domain": { + "name": "tenant_domain", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "tenant_id": { + "name": "tenant_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "domain": { + "name": "domain", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_primary": { + "name": "is_primary", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "tenant_domain_tenant_id_tenant_id_fk": { + "name": "tenant_domain_tenant_id_tenant_id_fk", + "tableFrom": "tenant_domain", + "tableTo": "tenant", + "columnsFrom": ["tenant_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "uq_tenant_domain_domain": { + "name": "uq_tenant_domain_domain", + "nullsNotDistinct": false, + "columns": ["domain"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.tenant": { + "name": "tenant", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "tenant_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'inactive'" + }, + "primary_domain": { + "name": "primary_domain", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_primary": { + "name": "is_primary", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "uq_tenant_slug": { + "name": "uq_tenant_slug", + "nullsNotDistinct": false, + "columns": ["slug"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.photo_sync_status": { + "name": "photo_sync_status", + "schema": "public", + "values": ["pending", "synced", "conflict"] + }, + "public.tenant_status": { + "name": "tenant_status", + "schema": "public", + "values": ["active", "inactive", "suspended"] + }, + "public.user_role": { + "name": "user_role", + "schema": "public", + "values": ["user", "admin", "superadmin"] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} diff --git a/be/packages/db/migrations/meta/_journal.json b/be/packages/db/migrations/meta/_journal.json index f54fa7c2..3879106c 100644 --- a/be/packages/db/migrations/meta/_journal.json +++ b/be/packages/db/migrations/meta/_journal.json @@ -22,6 +22,13 @@ "when": 1761586496779, "tag": "0002_funny_captain_cross", "breakpoints": true + }, + { + "idx": 3, + "version": "7", + "when": 1761917402844, + "tag": "0003_lovely_wendell_rand", + "breakpoints": true } ] } diff --git a/be/packages/db/package.json b/be/packages/db/package.json index a865cf02..add715d1 100644 --- a/be/packages/db/package.json +++ b/be/packages/db/package.json @@ -22,6 +22,6 @@ "zod": "^4.1.11" }, "devDependencies": { - "drizzle-kit": "0.31.5" + "drizzle-kit": "0.31.6" } } diff --git a/be/packages/db/src/schema.ts b/be/packages/db/src/schema.ts index df4aba99..6bac6027 100644 --- a/be/packages/db/src/schema.ts +++ b/be/packages/db/src/schema.ts @@ -1,5 +1,5 @@ import type { PhotoManifestItem } from '@afilmory/builder' -import { bigint, boolean, jsonb, pgEnum, pgTable, text, timestamp, unique } from 'drizzle-orm/pg-core' +import { bigint, boolean, index, jsonb, pgEnum, pgTable, text, timestamp, unique } from 'drizzle-orm/pg-core' import { generateId } from './snowflake' @@ -158,6 +158,23 @@ export const systemSettings = pgTable( (t) => [unique('uq_system_setting_key').on(t.key)], ) +export const reactions = pgTable( + 'reactions', + { + id: snowflakeId, + tenantId: text('tenant_id') + .notNull() + .references(() => tenants.id, { onDelete: 'cascade' }), + createdAt: timestamp('created_at', { mode: 'string' }).defaultNow().notNull(), + refKey: text('ref_key').notNull(), + reaction: text('reaction').notNull(), + }, + (t) => [ + index('idx_reactions_tenant_ref_key').on(t.tenantId, t.refKey), + unique('uq_reactions_tenant_ref_key').on(t.tenantId, t.refKey), + ], +) + export const photoAssets = pgTable( 'photo_asset', { @@ -195,6 +212,7 @@ export const dbSchema = { authAccounts, settings, systemSettings, + reactions, photoAssets, } diff --git a/be/packages/framework/package.json b/be/packages/framework/package.json index 62f49fd1..b36835c6 100644 --- a/be/packages/framework/package.json +++ b/be/packages/framework/package.json @@ -19,17 +19,17 @@ "ioredis": ">=5.8.0" }, "dependencies": { - "hono": "4.10.2", + "hono": "4.10.4", "picocolors": "1.1.1", "reflect-metadata": "0.2.2", "tsyringe": "4.10.0", "zod": "^4.1.11" }, "devDependencies": { - "@types/node": "^24.9.1", - "@vitest/coverage-v8": "4.0.3", + "@types/node": "^24.9.2", + "@vitest/coverage-v8": "4.0.6", "ioredis": "5.8.2", "unplugin-swc": "1.5.8", - "vitest": "4.0.3" + "vitest": "4.0.6" } } diff --git a/be/packages/task-queue/package.json b/be/packages/task-queue/package.json index c791dfbe..31484d46 100644 --- a/be/packages/task-queue/package.json +++ b/be/packages/task-queue/package.json @@ -22,9 +22,9 @@ "tsyringe": "^4.10.0" }, "devDependencies": { - "@types/node": "^24.9.1", - "@vitest/coverage-v8": "4.0.3", + "@types/node": "^24.9.2", + "@vitest/coverage-v8": "4.0.6", "ioredis": "^5.8.2", - "vitest": "4.0.3" + "vitest": "4.0.6" } } diff --git a/be/packages/utils/package.json b/be/packages/utils/package.json index b8e217a9..77661b16 100644 --- a/be/packages/utils/package.json +++ b/be/packages/utils/package.json @@ -19,6 +19,6 @@ "zod": "^4.1.11" }, "devDependencies": { - "@types/node": "^24.9.1" + "@types/node": "^24.9.2" } } diff --git a/builder.config.default.ts b/builder.config.default.ts index 55ce03a5..86b326c8 100644 --- a/builder.config.default.ts +++ b/builder.config.default.ts @@ -1,6 +1,6 @@ import os from 'node:os' -import { defineBuilderConfig } from '@afilmory/builder' +import { defineBuilderConfig, thumbnailStoragePlugin } from '@afilmory/builder' import { env } from './env.js' @@ -52,5 +52,5 @@ export default defineBuilderConfig(() => ({ workerConcurrency: 2, }, }, - plugins: [], + plugins: [thumbnailStoragePlugin()], })) diff --git a/package.json b/package.json index 33530cf4..dc036923 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "@afilmory/builder": "workspace:*", "@clack/prompts": "^0.11.0", "@innei/prettier": "1.0.0", - "@types/node": "24.9.1", + "@types/node": "24.9.2", "ast-kit": "2.1.3", "consola": "3.4.2", "dotenv-expand": "catalog:", diff --git a/packages/builder/package.json b/packages/builder/package.json index f49cfb6c..f7f1bf2b 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -12,15 +12,15 @@ "cli": "tsx src/cli.ts" }, "dependencies": { - "@aws-sdk/client-s3": "3.916.0", + "@aws-sdk/client-s3": "3.921.0", "@aws-sdk/node-http-handler": "3.374.0", - "@aws-sdk/s3-request-presigner": "3.916.0", + "@aws-sdk/s3-request-presigner": "3.921.0", "@vingle/bmp-js": "^0.2.5", "blurhash": "2.0.5", - "c12": "^1.11.2", + "c12": "^3.3.1", "dotenv-expand": "catalog:", "execa": "9.6.0", - "exiftool-vendored": "31.1.0", + "exiftool-vendored": "31.2.0", "heic-convert": "2.1.0", "heic-to": "1.3.0", "sharp": "0.34.4", @@ -28,7 +28,7 @@ }, "devDependencies": { "@afilmory/utils": "workspace:*", - "tsdown": "0.15.9" + "tsdown": "0.15.12" }, "publishConfig": { "access": "public", diff --git a/packages/builder/src/builder/builder.ts b/packages/builder/src/builder/builder.ts index cd4d78c8..f38aa566 100644 --- a/packages/builder/src/builder/builder.ts +++ b/packages/builder/src/builder/builder.ts @@ -18,7 +18,6 @@ import { StorageFactory, StorageManager } from '../storage/index.js' import type { BuilderConfig } from '../types/config.js' import type { AfilmoryManifest, CameraInfo, LensInfo } from '../types/manifest.js' import type { PhotoManifestItem, ProcessPhotoResult } from '../types/photo.js' -import { clone } from '../utils/clone.js' import { ClusterPool } from '../worker/cluster-pool.js' import { WorkerPool } from '../worker/pool.js' @@ -45,8 +44,7 @@ export class AfilmoryBuilder { private readonly pluginReferences: BuilderPluginConfigEntry[] constructor(config: BuilderConfig) { - // 创建配置副本,避免外部修改 - this.config = clone(config) + this.config = config this.pluginReferences = this.resolvePluginReferences() @@ -587,7 +585,7 @@ export class AfilmoryBuilder { * 获取当前配置 */ getConfig(): BuilderConfig { - return clone(this.config) + return Object.freeze(this.config) } /** diff --git a/packages/builder/src/config/defaults.ts b/packages/builder/src/config/defaults.ts index c244c326..b7d962fa 100644 --- a/packages/builder/src/config/defaults.ts +++ b/packages/builder/src/config/defaults.ts @@ -1,5 +1,6 @@ import os from 'node:os' +import thumbnailStoragePlugin from '../plugins/thumbnail-storage/index.js' import type { BuilderConfig } from '../types/config.js' export function createDefaultBuilderConfig(): BuilderConfig { @@ -51,6 +52,6 @@ export function createDefaultBuilderConfig(): BuilderConfig { workerConcurrency: 2, }, }, - plugins: [], + plugins: [thumbnailStoragePlugin()], } } diff --git a/packages/builder/src/config/helper.ts b/packages/builder/src/config/helper.ts new file mode 100644 index 00000000..0c20af9e --- /dev/null +++ b/packages/builder/src/config/helper.ts @@ -0,0 +1,5 @@ +import type { BuilderConfigInput } from '../types/config' + +export function defineBuilderConfig(config: BuilderConfigInput | (() => BuilderConfigInput)): BuilderConfigInput { + return typeof config === 'function' ? config() : config +} diff --git a/packages/builder/src/config/index.ts b/packages/builder/src/config/index.ts index 9544110b..fea123a2 100644 --- a/packages/builder/src/config/index.ts +++ b/packages/builder/src/config/index.ts @@ -12,10 +12,6 @@ export interface LoadBuilderConfigOptions { defaults?: BuilderConfig } -export function defineBuilderConfig(config: BuilderConfigInput | (() => BuilderConfigInput)): BuilderConfigInput { - return typeof config === 'function' ? config() : config -} - function normalizeBuilderConfig(defaults: BuilderConfig, input: BuilderConfigInput): BuilderConfig { const base = clone(defaults) const merged = merge(base, input as Record) as BuilderConfig diff --git a/packages/builder/src/index.ts b/packages/builder/src/index.ts index 6f3714c7..6811bf01 100644 --- a/packages/builder/src/index.ts +++ b/packages/builder/src/index.ts @@ -2,8 +2,8 @@ export * from '../../utils/src/u8array.js' export type { BuilderOptions, BuilderResult } from './builder/index.js' export { AfilmoryBuilder } from './builder/index.js' export { createDefaultBuilderConfig } from './config/defaults.js' +export { defineBuilderConfig } from './config/helper.js' export type { LoadBuilderConfigOptions } from './config/index.js' -export { defineBuilderConfig, loadBuilderConfig } from './config/index.js' export type { PhotoProcessingContext, ProcessedImageData } from './photo/image-pipeline.js' export { executePhotoProcessingPipeline, @@ -22,6 +22,8 @@ export type { LocalStoragePluginOptions } from './plugins/storage/local.js' export { default as localStoragePlugin } from './plugins/storage/local.js' export type { S3StoragePluginOptions } from './plugins/storage/s3.js' export { default as s3StoragePlugin } from './plugins/storage/s3.js' +export type { ThumbnailStoragePluginOptions } from './plugins/thumbnail-storage/index.js' +export { THUMBNAIL_PLUGIN_SYMBOL, default as thumbnailStoragePlugin } from './plugins/thumbnail-storage/index.js' export type { BuilderPlugin, BuilderPluginConfigEntry, diff --git a/packages/builder/src/photo/image-pipeline.ts b/packages/builder/src/photo/image-pipeline.ts index 9a66e476..eeeb3a07 100644 --- a/packages/builder/src/photo/image-pipeline.ts +++ b/packages/builder/src/photo/image-pipeline.ts @@ -13,6 +13,7 @@ import { preprocessImageBuffer, } from '../image/processor.js' import type { PluginRunState } from '../plugins/manager.js' +import { THUMBNAIL_PLUGIN_DATA_KEY } from '../plugins/thumbnail-storage/shared.js' import type { PhotoManifestItem, ProcessPhotoResult } from '../types/photo.js' import { shouldProcessPhoto } from './cache-manager.js' import { processExifData, processThumbnailAndBlurhash, processToneAnalysis } from './data-processors.js' @@ -162,6 +163,13 @@ export async function executePhotoProcessingPipeline( // 3. 处理缩略图和 blurhash const thumbnailResult = await processThumbnailAndBlurhash(imageBuffer, photoId, existingItem, options) + context.pluginData[THUMBNAIL_PLUGIN_DATA_KEY] = { + photoId, + fileName: `${photoId}.jpg`, + buffer: thumbnailResult.thumbnailBuffer, + localUrl: thumbnailResult.thumbnailUrl, + } + // 4. 处理 EXIF 数据 const exifData = await processExifData(imageBuffer, imageData.rawBuffer, photoKey, existingItem, options) diff --git a/packages/builder/src/plugins/thumbnail-storage/index.ts b/packages/builder/src/plugins/thumbnail-storage/index.ts new file mode 100644 index 00000000..2f001bc4 --- /dev/null +++ b/packages/builder/src/plugins/thumbnail-storage/index.ts @@ -0,0 +1,190 @@ +import { StorageManager } from '../../storage/index.js' +import type { StorageConfig } from '../../storage/interfaces.js' +import type { BuilderPlugin } from '../types.js' +import type { ThumbnailPluginData } from './shared.js' +import { + DEFAULT_CONTENT_TYPE, + DEFAULT_DIRECTORY, + THUMBNAIL_PLUGIN_DATA_KEY, + THUMBNAIL_PLUGIN_SYMBOL, +} from './shared.js' + +const PLUGIN_NAME = 'afilmory:thumbnail-storage' +const RUN_STATE_KEY = 'state' + +type UploadableStorageConfig = Exclude + +interface ThumbnailStoragePluginOptions { + directory?: string + storageConfig?: UploadableStorageConfig + contentType?: string +} + +interface ResolvedPluginConfig { + directory: string + remotePrefix: string + contentType: string + useDefaultStorage: boolean + storageConfig: UploadableStorageConfig | null + enabled: boolean +} + +interface PluginRunState { + uploaded: Set + urlCache: Map +} + +function normalizeDirectory(directory: string | undefined): string { + const value = directory?.trim() || DEFAULT_DIRECTORY + const normalized = value.replaceAll('\\', '/').replaceAll(/^\/+|\/+$/g, '') + return normalized || DEFAULT_DIRECTORY +} + +function trimSlashes(value: string | undefined | null): string | null { + if (!value) return null + const normalized = value.replaceAll('\\', '/').replaceAll(/^\/+|\/+$/g, '') + return normalized.length > 0 ? normalized : null +} + +function joinSegments(...segments: Array): string { + const filtered = segments + .map((segment) => (segment ?? '').replaceAll('\\', '/').replaceAll(/^\/+|\/+$/g, '')) + .filter((segment) => segment.length > 0) + return filtered.join('/') +} + +function resolveRemotePrefix(config: UploadableStorageConfig, directory: string): string { + switch (config.provider) { + case 's3': { + const base = trimSlashes(config.prefix) + return joinSegments(base, directory) + } + case 'github': { + return joinSegments(directory) + } + case 'local': { + return joinSegments(directory) + } + default: { + return joinSegments(directory) + } + } +} + +function getOrCreateRunState(container: Map): PluginRunState { + let state = container.get(RUN_STATE_KEY) as PluginRunState | undefined + if (!state) { + state = { + uploaded: new Set(), + urlCache: new Map(), + } + container.set(RUN_STATE_KEY, state) + } + return state +} + +export default function thumbnailStoragePlugin(options: ThumbnailStoragePluginOptions = {}): BuilderPlugin { + let resolved: ResolvedPluginConfig | null = null + let externalStorageManager: StorageManager | null = null + + const plugin: BuilderPlugin & { [THUMBNAIL_PLUGIN_SYMBOL]: true } = { + name: PLUGIN_NAME, + [THUMBNAIL_PLUGIN_SYMBOL]: true, + hooks: { + onInit: ({ builder, config, logger }) => { + const storageConfig = (options.storageConfig ?? config.storage) as StorageConfig + const directory = normalizeDirectory(options.directory) + const contentType = options.contentType ?? DEFAULT_CONTENT_TYPE + + if (storageConfig.provider === 'eagle') { + logger.thumbnail.warn('缩略图上传插件不支持 Eagle 存储提供商,已自动禁用。') + externalStorageManager = null + resolved = { + directory, + remotePrefix: '', + contentType, + useDefaultStorage: !options.storageConfig, + storageConfig: null, + enabled: false, + } + return + } + + const uploadableConfig = storageConfig as UploadableStorageConfig + const remotePrefix = resolveRemotePrefix(uploadableConfig, directory) + + resolved = { + directory, + remotePrefix, + contentType, + useDefaultStorage: !options.storageConfig, + storageConfig: uploadableConfig, + enabled: true, + } + + if (!options.storageConfig) { + builder.getStorageManager().addExcludePrefix(remotePrefix) + } else { + externalStorageManager = new StorageManager(uploadableConfig) + } + }, + afterPhotoProcess: async ({ builder, payload, runShared, logger }) => { + if (!resolved) { + logger.main.warn('Thumbnail storage plugin is not initialized correctly. Skipping upload.') + return + } + + if (!resolved.enabled) { + return + } + + const data = payload.context.pluginData[THUMBNAIL_PLUGIN_DATA_KEY] as ThumbnailPluginData | undefined + + if (!data || !data.buffer || !payload.result.item) { + return + } + + const storageManager = resolved.useDefaultStorage ? builder.getStorageManager() : externalStorageManager + + if (!storageManager) { + logger.main.warn('Thumbnail storage plugin could not resolve storage manager. Skipping upload.') + return + } + + const remoteKey = joinSegments(resolved.remotePrefix, data.fileName) + const state = getOrCreateRunState(runShared) + + if (!state.uploaded.has(remoteKey)) { + try { + await storageManager.uploadFile(remoteKey, data.buffer, { + contentType: resolved.contentType, + }) + state.uploaded.add(remoteKey) + } catch (error) { + logger.thumbnail.error(`上传缩略图失败:${remoteKey}`, error) + return + } + } + + let remoteUrl = state.urlCache.get(remoteKey) + if (!remoteUrl) { + try { + remoteUrl = await storageManager.generatePublicUrl(remoteKey) + state.urlCache.set(remoteKey, remoteUrl) + } catch (error) { + logger.thumbnail.error(`生成缩略图 URL 失败:${remoteKey}`, error) + return + } + } + + payload.result.item.thumbnailUrl = remoteUrl + }, + }, + } + + return plugin +} + +export type { ThumbnailStoragePluginOptions } + +export { THUMBNAIL_PLUGIN_SYMBOL } from './shared.js' diff --git a/packages/builder/src/plugins/thumbnail-storage/shared.ts b/packages/builder/src/plugins/thumbnail-storage/shared.ts new file mode 100644 index 00000000..77fc0600 --- /dev/null +++ b/packages/builder/src/plugins/thumbnail-storage/shared.ts @@ -0,0 +1,18 @@ +import type { Buffer } from 'node:buffer' + +export const THUMBNAIL_PLUGIN_DATA_KEY = 'afilmory:thumbnail-storage:data' + +/** + * Unique symbol identifier for the thumbnail storage plugin. + * Used for reliable plugin detection without fragile string matching. + */ +export const THUMBNAIL_PLUGIN_SYMBOL = Symbol.for('afilmory:thumbnail-storage') + +export interface ThumbnailPluginData { + photoId: string + fileName: string + buffer: Buffer | null + localUrl: string | null +} +export const DEFAULT_DIRECTORY = '.afilmory/thumbnails' +export const DEFAULT_CONTENT_TYPE = 'image/jpeg' diff --git a/packages/builder/src/storage/manager.ts b/packages/builder/src/storage/manager.ts index 38c8c359..bcd9b271 100644 --- a/packages/builder/src/storage/manager.ts +++ b/packages/builder/src/storage/manager.ts @@ -3,11 +3,24 @@ import type { StorageConfig, StorageObject, StorageProvider, StorageUploadOption export class StorageManager { private provider: StorageProvider + private readonly excludeFilters: Array<(key: string) => boolean> = [] constructor(config: StorageConfig) { this.provider = StorageFactory.createProvider(config) } + private applyExcludes(objects: T[]): T[] { + if (this.excludeFilters.length === 0) { + return objects + } + + return objects.filter((obj) => { + const { key } = obj + if (!key) return true + return !this.excludeFilters.some((filter) => filter(key)) + }) + } + /** * 从存储中获取文件 * @param key 文件的键值/路径 @@ -23,7 +36,8 @@ export class StorageManager { * @returns 图片文件对象数组 */ async listImages(): Promise { - return this.provider.listImages() + const objects = await this.provider.listImages() + return this.applyExcludes(objects) } /** @@ -31,7 +45,8 @@ export class StorageManager { * @returns 所有文件对象数组 */ async listAllFiles(): Promise { - return this.provider.listAllFiles() + const objects = await this.provider.listAllFiles() + return this.applyExcludes(objects) } /** @@ -49,8 +64,9 @@ export class StorageManager { * @returns Live Photo 配对映射 (图片 key -> 视频对象) */ async detectLivePhotos(allObjects?: StorageObject[]): Promise> { - const objects = allObjects || (await this.listAllFiles()) - return this.provider.detectLivePhotos(objects) + const sourceObjects = allObjects ?? (await this.provider.listAllFiles()) + const filtered = this.applyExcludes(sourceObjects) + return this.provider.detectLivePhotos(filtered) } async deleteFile(key: string): Promise { @@ -61,6 +77,20 @@ export class StorageManager { return await this.provider.uploadFile(key, data, options) } + addExcludeFilter(filter: (key: string) => boolean): void { + this.excludeFilters.push(filter) + } + + addExcludePrefix(prefix: string): void { + const normalized = prefix.replaceAll('\\', '/').replace(/^\/+/, '') + if (!normalized) { + return + } + + const effectivePrefix = normalized.endsWith('/') ? normalized : `${normalized}/` + this.addExcludeFilter((key) => key.startsWith(effectivePrefix)) + } + /** * 获取当前使用的存储提供商 * @returns 存储提供商实例 diff --git a/packages/docs/package.json b/packages/docs/package.json index c072bc8f..72fab18d 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -22,7 +22,7 @@ "@radix-ui/react-scroll-area": "1.2.10", "@tailwindcss/vite": "4.1.16", "@types/mdast": "^4.0.4", - "lucide-react": "^0.547.0", + "lucide-react": "^0.552.0", "mdast": "^3.0.0", "motion": "12.23.24", "next-themes": "^0.4.6", @@ -38,7 +38,7 @@ }, "devDependencies": { "@eslint/js": "^9.38.0", - "@shikijs/rehype": "^3.13.0", + "@shikijs/rehype": "^3.14.0", "@tailwindcss/postcss": "catalog:", "@tailwindcss/typography": "catalog:", "@types/glob": "^9.0.0", @@ -49,11 +49,11 @@ "@vitejs/plugin-react": "^5.1.0", "code-inspector-plugin": "1.2.10", "eslint": "^9.38.0", - "eslint-plugin-react-hooks": "^7.0.0", + "eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-react-refresh": "^0.4.24", "glob": "^11.0.3", "globals": "^16.4.0", - "shiki": "^3.13.0", + "shiki": "^3.14.0", "tailwind-scrollbar": "catalog:", "tailwindcss": "catalog:", "tailwindcss-animate": "catalog:", diff --git a/packages/ui/package.json b/packages/ui/package.json index 01eaedc9..073d8e7a 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -29,7 +29,7 @@ "clsx": "^2.1.1", "jotai": "^2.15.0", "motion": "^12.23.24", - "react-intersection-observer": "9.16.0", + "react-intersection-observer": "10.0.0", "sonner": "2.0.7", "tailwind-merge": "^3.3.1", "tailwind-variants": "^3.1.1", diff --git a/packages/ui/src/sonner.tsx b/packages/ui/src/sonner.tsx index 3544d3ee..4c90a708 100644 --- a/packages/ui/src/sonner.tsx +++ b/packages/ui/src/sonner.tsx @@ -7,7 +7,6 @@ const toastStyles = { group relative flex w-full items-center justify-between gap-3 rounded-2xl p-4 backdrop-blur-2xl duration-300 ease-out overflow-hidden max-w-md min-w-[320px] - font-theme [&]:border [&]:border-solid [&]:data-[type=default]:border-[rgba(255,92,0,0.2)] [&]:data-[type=success]:border-[rgba(40,205,65,0.2)] diff --git a/packages/webgl-viewer/package.json b/packages/webgl-viewer/package.json index b00f6374..39fb466c 100644 --- a/packages/webgl-viewer/package.json +++ b/packages/webgl-viewer/package.json @@ -19,9 +19,9 @@ }, "devDependencies": { "@types/react": "19.2.2", - "nbump": "2.1.7", + "nbump": "2.1.8", "react": "19.2.0", - "tsdown": "0.15.9", + "tsdown": "0.15.12", "unplugin-dts": "1.0.0-beta.6", "vite": "7.1.12" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9748453f..f12dddc1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -82,8 +82,8 @@ importers: specifier: 1.0.0 version: 1.0.0 '@types/node': - specifier: 24.9.1 - version: 24.9.1 + specifier: 24.9.2 + version: 24.9.2 ast-kit: specifier: 2.1.3 version: 2.1.3 @@ -134,19 +134,19 @@ importers: version: 0.15.3 vite: specifier: 7.1.12 - version: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + version: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vite-bundle-analyzer: specifier: 1.2.3 version: 1.2.3 vite-plugin-babel: specifier: 1.3.2 - version: 1.3.2(@babel/core@7.28.5)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 1.3.2(@babel/core@7.28.5)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) vite-plugin-checker: specifier: 0.11.0 - version: 0.11.0(eslint@9.38.0(jiti@2.6.1))(meow@13.2.0)(optionator@0.9.4)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 0.11.0(eslint@9.38.0(jiti@2.6.1))(meow@13.2.0)(optionator@0.9.4)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) vite-tsconfig-paths: specifier: 5.1.4 - version: 5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) apps/ssr: dependencies: @@ -167,7 +167,7 @@ importers: version: 2.1.1 drizzle-orm: specifier: 0.44.7 - version: 0.44.7(@types/pg@8.15.5)(@vercel/postgres@0.10.0)(kysely@0.28.8)(pg@8.16.3)(postgres@3.4.7) + version: 0.44.7(@types/pg@8.15.6)(@vercel/postgres@0.10.0)(kysely@0.28.8)(pg@8.16.3)(postgres@3.4.7) es-toolkit: specifier: 1.41.0 version: 1.41.0 @@ -221,11 +221,11 @@ importers: specifier: 'catalog:' version: 0.5.19(tailwindcss@4.1.16) '@types/node': - specifier: 24.9.1 - version: 24.9.1 + specifier: 24.9.2 + version: 24.9.2 '@types/pg': - specifier: 8.15.5 - version: 8.15.5 + specifier: 8.15.6 + version: 8.15.6 '@types/react': specifier: 19.2.2 version: 19.2.2 @@ -242,11 +242,11 @@ importers: specifier: 'catalog:' version: 12.0.3 drizzle-kit: - specifier: 0.31.5 - version: 0.31.5 + specifier: 0.31.6 + version: 0.31.6 next: - specifier: 16.0.0 - version: 16.0.0(@babel/core@7.28.5)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + specifier: 16.0.1 + version: 16.0.1(@babel/core@7.28.5)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) postcss: specifier: 8.5.6 version: 8.5.6 @@ -307,7 +307,7 @@ importers: version: 2.0.0(@babel/core@7.28.5)(@types/react@19.2.2)(acorn@8.15.0)(antd@5.26.2(luxon@3.7.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(framer-motion@12.23.24(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@maplibre/maplibre-gl-geocoder': specifier: ^1.9.1 - version: 1.9.1(maplibre-gl@5.9.0) + version: 1.9.1(maplibre-gl@5.10.0) '@radix-ui/react-avatar': specifier: 1.1.10 version: 1.1.10(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -330,8 +330,8 @@ importers: specifier: 10.3.1 version: 10.3.1(react@19.2.0) '@uswriting/exiftool': - specifier: 1.0.3 - version: 1.0.3 + specifier: 1.0.5 + version: 1.0.5 blurhash: specifier: 2.0.5 version: 2.0.5 @@ -363,14 +363,14 @@ importers: specifier: 8.2.0 version: 8.2.0 immer: - specifier: 10.1.3 - version: 10.1.3 + specifier: 10.2.0 + version: 10.2.0 jotai: specifier: 2.15.0 version: 2.15.0(@babel/core@7.28.5)(@babel/template@7.27.2)(@types/react@19.2.2)(react@19.2.0) maplibre-gl: - specifier: ^5.9.0 - version: 5.9.0 + specifier: ^5.10.0 + version: 5.10.0 masonic: specifier: 4.1.0 version: 4.1.0(react@19.2.0) @@ -378,8 +378,8 @@ importers: specifier: 12.23.24 version: 12.23.24(react-dom@19.2.0(react@19.2.0))(react@19.2.0) ofetch: - specifier: 1.4.1 - version: 1.4.1 + specifier: 1.5.0 + version: 1.5.0 react: specifier: 19.2.0 version: 19.2.0 @@ -396,26 +396,26 @@ importers: specifier: 1.0.4 version: 1.0.4(react@19.2.0) react-i18next: - specifier: 16.2.0 - version: 16.2.0(i18next@25.6.0(typescript@5.9.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + specifier: 16.2.3 + version: 16.2.3(i18next@25.6.0(typescript@5.9.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.3) react-image-gallery: specifier: 1.4.0 version: 1.4.0(react@19.2.0) react-intersection-observer: - specifier: 9.16.0 - version: 9.16.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + specifier: 10.0.0 + version: 10.0.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react-map-gl: specifier: ^8.1.0 - version: 8.1.0(mapbox-gl@3.13.0)(maplibre-gl@5.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + version: 8.1.0(mapbox-gl@3.13.0)(maplibre-gl@5.10.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react-remove-scroll: specifier: 2.7.1 version: 2.7.1(@types/react@19.2.2)(react@19.2.0) react-router: - specifier: 7.9.4 - version: 7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + specifier: 7.9.5 + version: 7.9.5(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react-scan: specifier: 0.4.3 - version: 0.4.3(@types/react@19.2.2)(next@16.0.0(@babel/core@7.28.5)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react-router-dom@6.30.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-router@7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(rollup@2.79.2) + version: 0.4.3(@types/react@19.2.2)(next@16.0.1(@babel/core@7.28.5)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react-router-dom@6.30.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-router@7.9.5(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(rollup@2.79.2) react-use-measure: specifier: 2.1.7 version: 2.1.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -454,7 +454,7 @@ importers: version: 4.1.12 zustand: specifier: 5.0.8 - version: 5.0.8(@types/react@19.2.2)(immer@10.1.3)(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0)) + version: 5.0.8(@types/react@19.2.2)(immer@10.2.0)(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0)) devDependencies: '@egoist/tailwindcss-icons': specifier: 'catalog:' @@ -473,10 +473,10 @@ importers: version: 0.5.19(tailwindcss@4.1.16) '@tailwindcss/vite': specifier: 4.1.16 - version: 4.1.16(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 4.1.16(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) '@types/node': - specifier: 24.9.1 - version: 24.9.1 + specifier: 24.9.2 + version: 24.9.2 '@types/react': specifier: 19.2.2 version: 19.2.2 @@ -485,7 +485,7 @@ importers: version: 19.2.2(@types/react@19.2.2) '@vitejs/plugin-react': specifier: ^5.1.0 - version: 5.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 5.1.0(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) ast-kit: specifier: 2.1.3 version: 2.1.3 @@ -496,8 +496,8 @@ importers: specifier: 1.2.10 version: 1.2.10 daisyui: - specifier: 5.3.9 - version: 5.3.9 + specifier: 5.3.10 + version: 5.3.10 execa: specifier: 9.6.0 version: 9.6.0 @@ -539,10 +539,10 @@ importers: version: 0.15.3 vite-plugin-html: specifier: 3.2.2 - version: 3.2.2(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 3.2.2(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) vite-plugin-pwa: specifier: 1.1.0 - version: 1.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(workbox-build@7.3.0(@types/babel__core@7.20.5))(workbox-window@7.3.0) + version: 1.1.0(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(workbox-build@7.3.0(@types/babel__core@7.20.5))(workbox-window@7.3.0) be: dependencies: @@ -596,20 +596,20 @@ importers: specifier: workspace:* version: link:../../../packages/utils '@aws-sdk/client-s3': - specifier: 3.916.0 - version: 3.916.0 + specifier: 3.921.0 + version: 3.921.0 '@hono/node-server': - specifier: ^1.19.5 - version: 1.19.5(hono@4.10.2) + specifier: ^1.19.6 + version: 1.19.6(hono@4.10.4) better-auth: - specifier: 1.3.29 - version: 1.3.29(next@16.0.0(@babel/core@7.28.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + specifier: 1.3.34 + version: 1.3.34(next@16.0.1(@babel/core@7.28.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) drizzle-orm: specifier: ^0.44.7 - version: 0.44.7(@types/pg@8.15.5)(@vercel/postgres@0.10.0)(kysely@0.28.8)(pg@8.16.3)(postgres@3.4.7) + version: 0.44.7(@types/pg@8.15.6)(@vercel/postgres@0.10.0)(kysely@0.28.8)(pg@8.16.3)(postgres@3.4.7) hono: - specifier: 4.10.2 - version: 4.10.2 + specifier: 4.10.4 + version: 4.10.4 pg: specifier: ^8.16.3 version: 8.16.3 @@ -627,11 +627,11 @@ importers: version: 4.1.12 devDependencies: '@types/node': - specifier: ^24.9.1 - version: 24.9.1 + specifier: ^24.9.2 + version: 24.9.2 '@types/pg': - specifier: 8.15.5 - version: 8.15.5 + specifier: 8.15.6 + version: 8.15.6 nodemon: specifier: 3.1.10 version: 3.1.10 @@ -640,16 +640,19 @@ importers: version: 1.5.8(@swc/core@1.13.5(@swc/helpers@0.5.17))(rollup@4.52.5) vite: specifier: 7.1.12 - version: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + version: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite-bundle-analyzer: + specifier: 1.2.3 + version: 1.2.3 vite-node: specifier: 3.2.4 - version: 3.2.4(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + version: 3.2.4(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vite-tsconfig-paths: specifier: 5.1.4 - version: 5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) vitest: - specifier: 4.0.3 - version: 4.0.3(@types/debug@4.1.12)(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + specifier: 4.0.6 + version: 4.0.6(@types/debug@4.1.12)(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) be/apps/dashboard: dependencies: @@ -711,8 +714,8 @@ importers: specifier: 5.90.5 version: 5.90.5(react@19.2.0) better-auth: - specifier: 1.3.29 - version: 1.3.29(next@16.0.0(@babel/core@7.28.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + specifier: 1.3.34 + version: 1.3.34(next@16.0.1(@babel/core@7.28.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) class-variance-authority: specifier: 0.7.1 version: 0.7.1 @@ -726,14 +729,14 @@ importers: specifier: 0.2.49 version: 0.2.49(react@19.2.0) immer: - specifier: 10.1.3 - version: 10.1.3 + specifier: 10.2.0 + version: 10.2.0 jotai: specifier: 2.15.0 version: 2.15.0(@babel/core@7.28.5)(@babel/template@7.27.2)(@types/react@19.2.2)(react@19.2.0) lucide-react: - specifier: 0.547.0 - version: 0.547.0(react@19.2.0) + specifier: 0.552.0 + version: 0.552.0(react@19.2.0) motion: specifier: 12.23.24 version: 12.23.24(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -741,8 +744,8 @@ importers: specifier: 5.1.6 version: 5.1.6 ofetch: - specifier: 1.4.1 - version: 1.4.1 + specifier: 1.5.0 + version: 1.5.0 radix-ui: specifier: 1.4.3 version: 1.4.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -753,11 +756,11 @@ importers: specifier: 19.2.0 version: 19.2.0(react@19.2.0) react-router: - specifier: 7.9.4 - version: 7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + specifier: 7.9.5 + version: 7.9.5(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react-scan: specifier: 0.4.3 - version: 0.4.3(@types/react@19.2.2)(next@16.0.0(@babel/core@7.28.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react-router-dom@6.30.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-router@7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(rollup@4.52.5) + version: 0.4.3(@types/react@19.2.2)(next@16.0.1(@babel/core@7.28.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react-router-dom@6.30.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-router@7.9.5(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(rollup@4.52.5) sonner: specifier: 2.0.7 version: 2.0.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -785,10 +788,10 @@ importers: version: 0.5.19(tailwindcss@4.1.16) '@tailwindcss/vite': specifier: 4.1.16 - version: 4.1.16(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 4.1.16(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) '@types/node': - specifier: 24.9.1 - version: 24.9.1 + specifier: 24.9.2 + version: 24.9.2 '@types/react': specifier: 19.2.2 version: 19.2.2 @@ -797,7 +800,7 @@ importers: version: 19.2.2(@types/react@19.2.2) '@vitejs/plugin-react': specifier: ^5.1.0 - version: 5.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 5.1.0(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) autoprefixer: specifier: 10.4.21 version: 10.4.21(postcss@8.5.6) @@ -851,16 +854,16 @@ importers: version: 5.9.3 vite: specifier: 7.1.12 - version: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + version: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vite-plugin-checker: specifier: 0.11.0 - version: 0.11.0(eslint@9.38.0(jiti@2.6.1))(meow@13.2.0)(optionator@0.9.4)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 0.11.0(eslint@9.38.0(jiti@2.6.1))(meow@13.2.0)(optionator@0.9.4)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) vite-plugin-route-builder: specifier: 0.4.1 version: 0.4.1 vite-tsconfig-paths: specifier: 5.1.4 - version: 5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) be/apps/demo: dependencies: @@ -882,16 +885,16 @@ importers: version: 5.9.3 vite: specifier: 7.1.12 - version: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + version: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vite-tsconfig-paths: specifier: 5.1.4 - version: 5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) be/packages/db: dependencies: drizzle-orm: specifier: ^0.44.7 - version: 0.44.7(@types/pg@8.15.5)(@vercel/postgres@0.10.0)(kysely@0.28.8)(pg@8.16.3)(postgres@3.4.7) + version: 0.44.7(@types/pg@8.15.6)(@vercel/postgres@0.10.0)(kysely@0.28.8)(pg@8.16.3)(postgres@3.4.7) nodejs-snowflake: specifier: ^2.0.1 version: 2.0.1 @@ -903,8 +906,8 @@ importers: version: 4.1.12 devDependencies: drizzle-kit: - specifier: 0.31.5 - version: 0.31.5 + specifier: 0.31.6 + version: 0.31.6 be/packages/env: dependencies: @@ -921,8 +924,8 @@ importers: be/packages/framework: dependencies: hono: - specifier: 4.10.2 - version: 4.10.2 + specifier: 4.10.4 + version: 4.10.4 picocolors: specifier: 1.1.1 version: 1.1.1 @@ -937,11 +940,11 @@ importers: version: 4.1.12 devDependencies: '@types/node': - specifier: ^24.9.1 - version: 24.9.1 + specifier: ^24.9.2 + version: 24.9.2 '@vitest/coverage-v8': - specifier: 4.0.3 - version: 4.0.3(vitest@4.0.3(@types/debug@4.1.12)(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + specifier: 4.0.6 + version: 4.0.6(vitest@4.0.6(@types/debug@4.1.12)(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) ioredis: specifier: 5.8.2 version: 5.8.2 @@ -949,8 +952,8 @@ importers: specifier: 1.5.8 version: 1.5.8(@swc/core@1.13.5(@swc/helpers@0.5.17))(rollup@4.52.5) vitest: - specifier: 4.0.3 - version: 4.0.3(@types/debug@4.1.12)(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + specifier: 4.0.6 + version: 4.0.6(@types/debug@4.1.12)(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) be/packages/redis: dependencies: @@ -968,17 +971,17 @@ importers: version: 4.10.0 devDependencies: '@types/node': - specifier: ^24.9.1 - version: 24.9.1 + specifier: ^24.9.2 + version: 24.9.2 '@vitest/coverage-v8': - specifier: 4.0.3 - version: 4.0.3(vitest@4.0.3(@types/debug@4.1.12)(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + specifier: 4.0.6 + version: 4.0.6(vitest@4.0.6(@types/debug@4.1.12)(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) ioredis: specifier: ^5.8.2 version: 5.8.2 vitest: - specifier: 4.0.3 - version: 4.0.3(@types/debug@4.1.12)(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + specifier: 4.0.6 + version: 4.0.6(@types/debug@4.1.12)(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) be/packages/utils: dependencies: @@ -990,20 +993,20 @@ importers: version: 4.1.12 devDependencies: '@types/node': - specifier: ^24.9.1 - version: 24.9.1 + specifier: ^24.9.2 + version: 24.9.2 packages/builder: dependencies: '@aws-sdk/client-s3': - specifier: 3.916.0 - version: 3.916.0 + specifier: 3.921.0 + version: 3.921.0 '@aws-sdk/node-http-handler': specifier: 3.374.0 version: 3.374.0 '@aws-sdk/s3-request-presigner': - specifier: 3.916.0 - version: 3.916.0 + specifier: 3.921.0 + version: 3.921.0 '@vingle/bmp-js': specifier: ^0.2.5 version: 0.2.5 @@ -1011,8 +1014,8 @@ importers: specifier: 2.0.5 version: 2.0.5 c12: - specifier: ^1.11.2 - version: 1.11.2(magicast@0.3.5) + specifier: ^3.3.1 + version: 3.3.1(magicast@0.3.5) dotenv-expand: specifier: 'catalog:' version: 12.0.3 @@ -1020,8 +1023,8 @@ importers: specifier: 9.6.0 version: 9.6.0 exiftool-vendored: - specifier: 31.1.0 - version: 31.1.0 + specifier: 31.2.0 + version: 31.2.0 heic-convert: specifier: 2.1.0 version: 2.1.0 @@ -1039,8 +1042,8 @@ importers: specifier: workspace:* version: link:../utils tsdown: - specifier: 0.15.9 - version: 0.15.9(typescript@5.9.3) + specifier: 0.15.12 + version: 0.15.12(typescript@5.9.3) packages/data: dependencies: @@ -1070,13 +1073,13 @@ importers: version: 1.2.10(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@tailwindcss/vite': specifier: 4.1.16 - version: 4.1.16(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 4.1.16(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) '@types/mdast': specifier: ^4.0.4 version: 4.0.4 lucide-react: - specifier: ^0.547.0 - version: 0.547.0(react@19.2.0) + specifier: ^0.552.0 + version: 0.552.0(react@19.2.0) mdast: specifier: ^3.0.0 version: 3.0.0 @@ -1118,8 +1121,8 @@ importers: specifier: ^9.38.0 version: 9.38.0 '@shikijs/rehype': - specifier: ^3.13.0 - version: 3.13.0 + specifier: ^3.14.0 + version: 3.14.0 '@tailwindcss/postcss': specifier: 'catalog:' version: 4.1.16 @@ -1143,7 +1146,7 @@ importers: version: 1.0.0 '@vitejs/plugin-react': specifier: ^5.1.0 - version: 5.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 5.1.0(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) code-inspector-plugin: specifier: 1.2.10 version: 1.2.10 @@ -1151,8 +1154,8 @@ importers: specifier: ^9.38.0 version: 9.38.0(jiti@2.6.1) eslint-plugin-react-hooks: - specifier: ^7.0.0 - version: 7.0.0(eslint@9.38.0(jiti@2.6.1)) + specifier: ^7.0.1 + version: 7.0.1(eslint@9.38.0(jiti@2.6.1)) eslint-plugin-react-refresh: specifier: ^0.4.24 version: 0.4.24(eslint@9.38.0(jiti@2.6.1)) @@ -1163,8 +1166,8 @@ importers: specifier: ^16.4.0 version: 16.4.0 shiki: - specifier: ^3.13.0 - version: 3.13.0 + specifier: ^3.14.0 + version: 3.14.0 tailwind-scrollbar: specifier: 'catalog:' version: 4.0.2(react@19.2.0)(tailwindcss@4.1.16) @@ -1191,7 +1194,7 @@ importers: version: 8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3) vite: specifier: ^7.1.12 - version: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + version: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) packages/hooks: dependencies: @@ -1269,8 +1272,8 @@ importers: specifier: ^12.23.24 version: 12.23.24(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react-intersection-observer: - specifier: 9.16.0 - version: 9.16.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + specifier: 10.0.0 + version: 10.0.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) sonner: specifier: 2.0.7 version: 2.0.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -1319,20 +1322,20 @@ importers: specifier: 19.2.2 version: 19.2.2 nbump: - specifier: 2.1.7 - version: 2.1.7(conventional-commits-filter@5.0.0)(magicast@0.3.5) + specifier: 2.1.8 + version: 2.1.8(conventional-commits-filter@5.0.0)(magicast@0.3.5) react: specifier: 19.2.0 version: 19.2.0 tsdown: - specifier: 0.15.9 - version: 0.15.9(typescript@5.9.3) + specifier: 0.15.12 + version: 0.15.12(typescript@5.9.3) unplugin-dts: specifier: 1.0.0-beta.6 - version: 1.0.0-beta.6(@microsoft/api-extractor@7.52.13(@types/node@24.9.1))(esbuild@0.25.11)(rollup@4.52.5)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 1.0.0-beta.6(@microsoft/api-extractor@7.52.13(@types/node@24.9.2))(esbuild@0.25.11)(rollup@4.52.5)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) vite: specifier: 7.1.12 - version: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + version: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) packages: @@ -1418,89 +1421,88 @@ packages: '@aws-crypto/util@5.2.0': resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - '@aws-sdk/client-s3@3.916.0': - resolution: {integrity: sha512-myfO8UkJzF3wxLUV1cKzzxI1oVOe+tsEyUypFt8yrs0WT0usNfjpUOmA4XNjp/wRClpImkEHT0XC1p6xQCuktQ==} + '@aws-sdk/client-s3@3.921.0': + resolution: {integrity: sha512-vwe+OmgsducnvzouQDKRXyzZqMY4CCdlh+XdPJZz7LH+v7kYvsqIB0PiRMhcDc4d+QUOw6oZgY3V3Spi0twU/Q==} engines: {node: '>=18.0.0'} - '@aws-sdk/client-sso@3.916.0': - resolution: {integrity: sha512-Eu4PtEUL1MyRvboQnoq5YKg0Z9vAni3ccebykJy615xokVZUdA3di2YxHM/hykDQX7lcUC62q9fVIvh0+UNk/w==} + '@aws-sdk/client-sso@3.921.0': + resolution: {integrity: sha512-qWyT7WikdkPRAMuWidZ2l8jcQAPwNjvLcFZ/8K+oCAaMLt0LKLd7qeTwZ5tZFNqRNPXKfE8MkvAjyqSpE3i2yg==} engines: {node: '>=18.0.0'} - '@aws-sdk/core@3.916.0': - resolution: {integrity: sha512-1JHE5s6MD5PKGovmx/F1e01hUbds/1y3X8rD+Gvi/gWVfdg5noO7ZCerpRsWgfzgvCMZC9VicopBqNHCKLykZA==} + '@aws-sdk/core@3.921.0': + resolution: {integrity: sha512-1eiD9ZO9cvEHdQUn/pwJVGN9LXg6D0O7knGVA0TA/v7nFSYy0n8RYG8vdnlcoYYnV1BcHgaf4KmRVMOszafNZQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-env@3.916.0': - resolution: {integrity: sha512-3gDeqOXcBRXGHScc6xb7358Lyf64NRG2P08g6Bu5mv1Vbg9PKDyCAZvhKLkG7hkdfAM8Yc6UJNhbFxr1ud/tCQ==} + '@aws-sdk/credential-provider-env@3.921.0': + resolution: {integrity: sha512-RGG+zZdOYGJBQ8+L7BI6v41opoF8knErMtBZAUGcD3gvWEhjatc7lSbIpBeYWbTaWPPLHQU+ZVbmQ/jRLBgefw==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-http@3.916.0': - resolution: {integrity: sha512-NmooA5Z4/kPFJdsyoJgDxuqXC1C6oPMmreJjbOPqcwo6E/h2jxaG8utlQFgXe5F9FeJsMx668dtxVxSYnAAqHQ==} + '@aws-sdk/credential-provider-http@3.921.0': + resolution: {integrity: sha512-TAv08Ow0oF/olV4DTLoPDj46KMk35bL1IUCfToESDrWk1TOSur7d4sCL0p/7dUsAxS244cEgeyIIijKNtxj2AA==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-ini@3.916.0': - resolution: {integrity: sha512-iR0FofvdPs87o6MhfNPv0F6WzB4VZ9kx1hbvmR7bSFCk7l0gc7G4fHJOg4xg2lsCptuETboX3O/78OQ2Djeakw==} + '@aws-sdk/credential-provider-ini@3.921.0': + resolution: {integrity: sha512-MUSRYGiMRq5NRGPRgJ7Nuh7GqXzE9iteAwdbzMJ4pnImgr7CjeWDihCIGk+gKLSG+NoRVVJM0V9PA4rxFir0Pg==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-node@3.916.0': - resolution: {integrity: sha512-8TrMpHqct0zTalf2CP2uODiN/PH9LPdBC6JDgPVK0POELTT4ITHerMxIhYGEiKN+6E4oRwSjM/xVTHCD4nMcrQ==} + '@aws-sdk/credential-provider-node@3.921.0': + resolution: {integrity: sha512-bxUAqRyo49WzKWn/XS0d8QXT9GydY/ew5m58PYfSMwYfmwBZXx1GLSWe3tZnefm6santFiqmIWfMmeRWdygKmQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-process@3.916.0': - resolution: {integrity: sha512-SXDyDvpJ1+WbotZDLJW1lqP6gYGaXfZJrgFSXIuZjHb75fKeNRgPkQX/wZDdUvCwdrscvxmtyJorp2sVYkMcvA==} + '@aws-sdk/credential-provider-process@3.921.0': + resolution: {integrity: sha512-DM62ooWI/aZ+ENBcLszuKmOkiICf6p4vYO2HgA3Cy2OEsTsjb67NEcntksxpZkD3mSIrCy/Qi4Z7tc77gle2Nw==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-sso@3.916.0': - resolution: {integrity: sha512-gu9D+c+U/Dp1AKBcVxYHNNoZF9uD4wjAKYCjgSN37j4tDsazwMEylbbZLuRNuxfbXtizbo4/TiaxBXDbWM7AkQ==} + '@aws-sdk/credential-provider-sso@3.921.0': + resolution: {integrity: sha512-Nh5jPJ6Y6nu3cHzZnq394lGXE5YO8Szke5zlATbNI7Tl0QJR65GE0IZsBcjzRMGpYX6ENCqPDK8FmklkmCYyVQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-web-identity@3.916.0': - resolution: {integrity: sha512-VFnL1EjHiwqi2kR19MLXjEgYBuWViCuAKLGSFGSzfFF/+kSpamVrOSFbqsTk8xwHan8PyNnQg4BNuusXwwLoIw==} + '@aws-sdk/credential-provider-web-identity@3.921.0': + resolution: {integrity: sha512-VWcbgB2/shPPK674roHV4s8biCtvn0P/05EbTqy9WeyM5Oblx291gRGccyDhQbJbOL/6diRPBM08tlKPlBKNfw==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-bucket-endpoint@3.914.0': - resolution: {integrity: sha512-mHLsVnPPp4iq3gL2oEBamfpeETFV0qzxRHmcnCfEP3hualV8YF8jbXGmwPCPopUPQDpbYDBHYtXaoClZikCWPQ==} + '@aws-sdk/middleware-bucket-endpoint@3.921.0': + resolution: {integrity: sha512-D4AVjNAmy7KYycM/mOzbQRZbOOU0mY4T3nmW//CE8amqsAmmeIW6ff2AH/5yGRp8aNjQInZ9npXHTThKc4a+LA==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-expect-continue@3.916.0': - resolution: {integrity: sha512-p7TMLZZ/j5NbC7/cz7xNgxLz/OHYuh91MeCZdCedJiyh3rx6gunFtl9eiDtrh+Y8hjs0EwR0zYIuhd6pL1O8zg==} - engines: {node: '>=18.0.0'} - deprecated: '@aws-sdk/middleware-expect-continue v3.916.0 contains an accidental console.log statement (https://github.com/aws/aws-sdk-js-v3/pull/7454), please upgrade to v3.917.0+' - - '@aws-sdk/middleware-flexible-checksums@3.916.0': - resolution: {integrity: sha512-CBRRg6slHHBYAm26AWY/pECHK0vVO/peDoNhZiAzUNt4jV6VftotjszEJ904pKGOr7/86CfZxtCnP3CCs3lQjA==} + '@aws-sdk/middleware-expect-continue@3.921.0': + resolution: {integrity: sha512-XnHLbyu6uZlS8DbxpB1TFWYCi+IOdf8PAfijkiOCdl1vf9pBZBE45xvghSd+Ck0EqlKQl4mEy9sB0Vv1ERnMfQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-host-header@3.914.0': - resolution: {integrity: sha512-7r9ToySQ15+iIgXMF/h616PcQStByylVkCshmQqcdeynD/lCn2l667ynckxW4+ql0Q+Bo/URljuhJRxVJzydNA==} + '@aws-sdk/middleware-flexible-checksums@3.921.0': + resolution: {integrity: sha512-8bgPdSpcAPeXDnxMGnL2Nj2EfWhU95U7Q+C+XvAPlkSPSi0tFU2F1/D6hdVBQ5MCjL9areamAt2qO/Tt3+IEUw==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-location-constraint@3.914.0': - resolution: {integrity: sha512-Mpd0Sm9+GN7TBqGnZg1+dO5QZ/EOYEcDTo7KfvoyrXScMlxvYm9fdrUVMmLdPn/lntweZGV3uNrs+huasGOOTA==} + '@aws-sdk/middleware-host-header@3.921.0': + resolution: {integrity: sha512-eX1Ka29XzuEcXG4YABTwyLtPLchjmcjSjaq4irKJTFkxSYzX7gjoKt18rh/ZzOWOSqi23+cpjvBacL4VBKvE2Q==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-logger@3.914.0': - resolution: {integrity: sha512-/gaW2VENS5vKvJbcE1umV4Ag3NuiVzpsANxtrqISxT3ovyro29o1RezW/Avz/6oJqjnmgz8soe9J1t65jJdiNg==} + '@aws-sdk/middleware-location-constraint@3.921.0': + resolution: {integrity: sha512-KjYtPvAks/WgCc9sRbqTM0MP3+utMT+OJ1NN61kyiCiUJuMyKFb3olhCUIJHajP5trTsXCiwFsuysj9x2iupJw==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-recursion-detection@3.914.0': - resolution: {integrity: sha512-yiAjQKs5S2JKYc+GrkvGMwkUvhepXDigEXpSJqUseR/IrqHhvGNuOxDxq+8LbDhM4ajEW81wkiBbU+Jl9G82yQ==} + '@aws-sdk/middleware-logger@3.921.0': + resolution: {integrity: sha512-14Qqp8wisKGj/2Y22OfO5jTBG5Xez+p3Zr2piAtz7AcbY8vBEoZbd6f+9lwwVFC73Aobkau223wzKbGT8HYQMw==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-sdk-s3@3.916.0': - resolution: {integrity: sha512-pjmzzjkEkpJObzmTthqJPq/P13KoNFuEi/x5PISlzJtHofCNcyXeVAQ90yvY2dQ6UXHf511Rh1/ytiKy2A8M0g==} + '@aws-sdk/middleware-recursion-detection@3.921.0': + resolution: {integrity: sha512-MYU5oI2b97M7u1dC1nt7SiGEvvLrQDlzV6hq9CB5TYX2glgbyvkaS//1Tjm87VF6qVSf5jYfwFDPeFGd8O1NrQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-ssec@3.914.0': - resolution: {integrity: sha512-V1Oae/oLVbpNb9uWs+v80GKylZCdsbqs2c2Xb1FsAUPtYeSnxFuAWsF3/2AEMSSpFe0dTC5KyWr/eKl2aim9VQ==} + '@aws-sdk/middleware-sdk-s3@3.921.0': + resolution: {integrity: sha512-u4fkE6sn5KWojhPUeDIqRx0BJlQug60PzAnLPlxeIvy2+ZeTSY64WYwF6V7wIZCf1RIstiBA/hQUsX07LfbvNg==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-user-agent@3.916.0': - resolution: {integrity: sha512-mzF5AdrpQXc2SOmAoaQeHpDFsK2GE6EGcEACeNuoESluPI2uYMpuuNMYrUufdnIAIyqgKlis0NVxiahA5jG42w==} + '@aws-sdk/middleware-ssec@3.921.0': + resolution: {integrity: sha512-hxu8bzu99afvBwyrq2YLUc6fOIR4kipGFsdTAfkXAoniYCaMA4eehSlvfWhbgUnNHbXb/KoP+lk8UTnx+gU8vQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/nested-clients@3.916.0': - resolution: {integrity: sha512-tgg8e8AnVAer0rcgeWucFJ/uNN67TbTiDHfD+zIOPKep0Z61mrHEoeT/X8WxGIOkEn4W6nMpmS4ii8P42rNtnA==} + '@aws-sdk/middleware-user-agent@3.921.0': + resolution: {integrity: sha512-gXgokMBTPZAbQMm1+JOxItqA81aSFK6n7V2mAwxdmHjzCUZacX5RzkVPNbSaPPgDkroYnIzK09EusIpM6dLaqw==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/nested-clients@3.921.0': + resolution: {integrity: sha512-GV9aV8WqH/EWo4x3T5BrYb2ph1yfYuzUXZc0hhvxbFbDKD8m2fX9menao3Mgm7E5C68Su392u+MD9SGmGCmfKQ==} engines: {node: '>=18.0.0'} '@aws-sdk/node-http-handler@3.374.0': @@ -1508,47 +1510,47 @@ packages: engines: {node: '>=14.0.0'} deprecated: This package has moved to @smithy/node-http-handler - '@aws-sdk/region-config-resolver@3.914.0': - resolution: {integrity: sha512-KlmHhRbn1qdwXUdsdrJ7S/MAkkC1jLpQ11n+XvxUUUCGAJd1gjC7AjxPZUM7ieQ2zcb8bfEzIU7al+Q3ZT0u7Q==} + '@aws-sdk/region-config-resolver@3.921.0': + resolution: {integrity: sha512-cSycw4wXcvsrssUdcEaeYQhQcZYVsBwHtgATh9HcIm01PrMV0lV71vcoyZ+9vUhwHwchRT6dItAyTHSQxwjvjg==} engines: {node: '>=18.0.0'} - '@aws-sdk/s3-request-presigner@3.916.0': - resolution: {integrity: sha512-XkHIhRISbdQHZ08Tq5Zt6A4n49mjVvcZd/PeY1SPCv47rzLnxdfxVSuEFynAg3Lgw/f/iHdv3lok2PAesCvi4A==} + '@aws-sdk/s3-request-presigner@3.921.0': + resolution: {integrity: sha512-OCH0jBL0w3hTHXWLkbgpdWkchl+6RqV4iVWMHjoknSW7uEJv2y0QfQOplxi79MgNx42ACXgUxRGnyJzV7FuhqA==} engines: {node: '>=18.0.0'} - '@aws-sdk/signature-v4-multi-region@3.916.0': - resolution: {integrity: sha512-fuzUMo6xU7e0NBzBA6TQ4FUf1gqNbg4woBSvYfxRRsIfKmSMn9/elXXn4sAE5UKvlwVQmYnb6p7dpVRPyFvnQA==} + '@aws-sdk/signature-v4-multi-region@3.921.0': + resolution: {integrity: sha512-pFtJXtrf8cOsCgEb2OoPwQP4BKrnwIq69FuLowvWrXllFntAoAdEYaj9wNxPyl4pGqvo/9zO9CtkMb53PNxmWQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/token-providers@3.916.0': - resolution: {integrity: sha512-13GGOEgq5etbXulFCmYqhWtpcEQ6WI6U53dvXbheW0guut8fDFJZmEv7tKMTJgiybxh7JHd0rWcL9JQND8DwoQ==} + '@aws-sdk/token-providers@3.921.0': + resolution: {integrity: sha512-d+w6X7ykqXirFBF+dYyK5Ntw0KmO2sgMj+JLR/vAe1vaR8/Fuqs3yOAFU7yNEzpcnbLJmMznxKpht03CSEMh4Q==} engines: {node: '>=18.0.0'} - '@aws-sdk/types@3.914.0': - resolution: {integrity: sha512-kQWPsRDmom4yvAfyG6L1lMmlwnTzm1XwMHOU+G5IFlsP4YEaMtXidDzW/wiivY0QFrhfCz/4TVmu0a2aPU57ug==} + '@aws-sdk/types@3.921.0': + resolution: {integrity: sha512-mqEG8+vFh5w0ZZC+R8VCOdSk998Hy93pIDuwYpfMAWgYwVhFaIMOLn1fZw0w2DhTs5+ONHHwMJ6uVXtuuqOLQQ==} engines: {node: '>=18.0.0'} '@aws-sdk/util-arn-parser@3.893.0': resolution: {integrity: sha512-u8H4f2Zsi19DGnwj5FSZzDMhytYF/bCh37vAtBsn3cNDL3YG578X5oc+wSX54pM3tOxS+NY7tvOAo52SW7koUA==} engines: {node: '>=18.0.0'} - '@aws-sdk/util-endpoints@3.916.0': - resolution: {integrity: sha512-bAgUQwvixdsiGNcuZSDAOWbyHlnPtg8G8TyHD6DTfTmKTHUW6tAn+af/ZYJPXEzXhhpwgJqi58vWnsiDhmr7NQ==} + '@aws-sdk/util-endpoints@3.921.0': + resolution: {integrity: sha512-kuJYRqug6V8gOg401BuK4w4IAVO3575VDR8iYiFw0gPwNIfOXvdlChfsJQoREqwJfif45J4eSmUsFtMfx87BQg==} engines: {node: '>=18.0.0'} - '@aws-sdk/util-format-url@3.914.0': - resolution: {integrity: sha512-QpdkoQjvPaYyzZwgk41vFyHQM5s0DsrsbQ8IoPUggQt4HaJUvmL1ShwMcSldbgdzwiRMqXUK8q7jrqUvkYkY6w==} + '@aws-sdk/util-format-url@3.921.0': + resolution: {integrity: sha512-ubU5/w/LERnELxgUKGQcVBlbcZaKGnCM9yuNqRuOuQeOKn+O6TLtFLxafrAcO0Ss1vwhoG5LEELFIykjE0soWQ==} engines: {node: '>=18.0.0'} '@aws-sdk/util-locate-window@3.893.0': resolution: {integrity: sha512-T89pFfgat6c8nMmpI8eKjBcDcgJq36+m9oiXbcUzeU55MP9ZuGgBomGjGnHaEyF36jenW9gmg3NfZDm0AO2XPg==} engines: {node: '>=18.0.0'} - '@aws-sdk/util-user-agent-browser@3.914.0': - resolution: {integrity: sha512-rMQUrM1ECH4kmIwlGl9UB0BtbHy6ZuKdWFrIknu8yGTRI/saAucqNTh5EI1vWBxZ0ElhK5+g7zOnUuhSmVQYUA==} + '@aws-sdk/util-user-agent-browser@3.921.0': + resolution: {integrity: sha512-buhv/ICWr4Nt8bquHOejCiVikBsfEYw4/HSc9U050QebRXIakt50zKYaWDQw4iCMeeqCiwE9mElEaXJAysythg==} - '@aws-sdk/util-user-agent-node@3.916.0': - resolution: {integrity: sha512-CwfWV2ch6UdjuSV75ZU99N03seEUb31FIUrXBnwa6oONqj/xqXwrxtlUMLx6WH3OJEE4zI3zt5PjlTdGcVwf4g==} + '@aws-sdk/util-user-agent-node@3.921.0': + resolution: {integrity: sha512-Ilftai6AMAU1cEaUqIiTxkyj1NupLhP9Eq8HRfVuIH8489J2wLCcOyiLklAgSzBNmrxW+fagxkY+Dg0lFwmcVA==} engines: {node: '>=18.0.0'} peerDependencies: aws-crt: '>=1.0.0' @@ -1556,12 +1558,12 @@ packages: aws-crt: optional: true - '@aws-sdk/xml-builder@3.914.0': - resolution: {integrity: sha512-k75evsBD5TcIjedycYS7QXQ98AmOtbnxRJOPtCo0IwYRmy7UvqgS/gBL5SmrIqeV6FDSYRQMgdBxSMp6MLmdew==} + '@aws-sdk/xml-builder@3.921.0': + resolution: {integrity: sha512-LVHg0jgjyicKKvpNIEMXIMr1EBViESxcPkqfOlT+X1FkmUMTNZEEVF18tOJg4m4hV5vxtkWcqtr4IEeWa1C41Q==} engines: {node: '>=18.0.0'} - '@aws/lambda-invoke-store@0.0.1': - resolution: {integrity: sha512-ORHRQ2tmvnBXc8t/X9Z8IcSbBA4xTLKuN873FopzklHMeqBst7YG0d+AX97inkvDX+NChYtSr+qGfcqGFaI8Zw==} + '@aws/lambda-invoke-store@0.1.1': + resolution: {integrity: sha512-RcLam17LdlbSOSp9VxmUu1eI6Mwxp+OwhD2QhiSNmNCzoDb0EeUXTD2n/WbcnrAYMGlmf05th6QYq23VqvJqpA==} engines: {node: '>=18.0.0'} '@babel/code-frame@7.27.1': @@ -2153,8 +2155,8 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - '@better-auth/core@1.3.29': - resolution: {integrity: sha512-Ka2mg4qZACFaLY7DOGFXv1Ma8CkF17k0ClUd2U/ZJbbSoEPI5gnVguEmakJB6HFYswszeZh2295IFORtW9wf7A==} + '@better-auth/core@1.3.34': + resolution: {integrity: sha512-rt/Bgl0Xa8OQ2DUMKCZEJ8vL9kUw4NCJsBP9Sj9uRhbsK8NEMPiznUOFMkUY2FvrslvfKN7H/fivwyHz9c7HzQ==} peerDependencies: '@better-auth/utils': 0.3.0 '@better-fetch/fetch': 1.1.18 @@ -2163,8 +2165,8 @@ packages: kysely: ^0.28.5 nanostores: ^1.0.1 - '@better-auth/telemetry@1.3.29': - resolution: {integrity: sha512-1BFh3YulYDrwWcUkfEWddcrcApACyI4wtrgq3NBd9y+tilBRjWTCWEPuRqJrfM3a5F1ZSqsvOYfFG1XZbkxlVw==} + '@better-auth/telemetry@1.3.34': + resolution: {integrity: sha512-aQZ3wN90YMqV49diWxAMe1k7s2qb55KCsedCZne5PlgCjU4s3YtnqyjC5FEpzw2KY8l8rvR7DMAsDl13NjObKA==} '@better-auth/utils@0.3.0': resolution: {integrity: sha512-W+Adw6ZA6mgvnSnhOki270rwJ42t4XzSK6YWGF//BbVXL6SwCLWfyzBc1lN2m/4RM28KubdBKQ4X5VMoLRNPQw==} @@ -2961,8 +2963,8 @@ packages: '@hexagon/base64@1.1.28': resolution: {integrity: sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==} - '@hono/node-server@1.19.5': - resolution: {integrity: sha512-iBuhh+uaaggeAuf+TftcjZyWh2GEgZcVGXkNtskLVoWaXhnJtC5HLHrU8W1KHDoucqO1MswwglmkWLFyiDn4WQ==} + '@hono/node-server@1.19.6': + resolution: {integrity: sha512-Shz/KjlIeAhfiuE93NDKVdZ7HdBVLQAfdbaXEaoAVO3ic9ibRSLGIQGkcBbFyuLr+7/1D5ZCINM8B+6IvXeMtw==} engines: {node: '>=18.14.1'} peerDependencies: hono: ^4 @@ -3254,8 +3256,8 @@ packages: resolution: {integrity: sha512-cOZZOVhDSulgK0meTsTkmNXb1ahVvmTmWmfx9gRBwc6hq98wS9JP35ESIoNq3xqEan+UN+gn8187Z6E4NKhLsw==} hasBin: true - '@maplibre/maplibre-gl-style-spec@24.3.0': - resolution: {integrity: sha512-CTJc/Nvldv+GNQuis29VnyV0TYsFTgQBY3SNagTzZ28oHDsDYJ7LwEmfick4Z30wPwI/4gXe3se8PH2IIfLx2g==} + '@maplibre/maplibre-gl-style-spec@24.3.1': + resolution: {integrity: sha512-TUM5JD40H2mgtVXl5IwWz03BuQabw8oZQLJTmPpJA0YTYF+B+oZppy5lNMO6bMvHzB+/5mxqW9VLG3wFdeqtOw==} hasBin: true '@maplibre/vt-pbf@4.0.3': @@ -3303,53 +3305,53 @@ packages: '@neondatabase/serverless@0.9.5': resolution: {integrity: sha512-siFas6gItqv6wD/pZnvdu34wEqgG3nSE6zWZdq5j2DEsa+VvX8i/5HXJOo06qrw5axPXn+lGCxeR+NLaSPIXug==} - '@next/env@16.0.0': - resolution: {integrity: sha512-s5j2iFGp38QsG1LWRQaE2iUY3h1jc014/melHFfLdrsMJPqxqDQwWNwyQTcNoUSGZlCVZuM7t7JDMmSyRilsnA==} + '@next/env@16.0.1': + resolution: {integrity: sha512-LFvlK0TG2L3fEOX77OC35KowL8D7DlFF45C0OvKMC4hy8c/md1RC4UMNDlUGJqfCoCS2VWrZ4dSE6OjaX5+8mw==} - '@next/swc-darwin-arm64@16.0.0': - resolution: {integrity: sha512-/CntqDCnk5w2qIwMiF0a9r6+9qunZzFmU0cBX4T82LOflE72zzH6gnOjCwUXYKOBlQi8OpP/rMj8cBIr18x4TA==} + '@next/swc-darwin-arm64@16.0.1': + resolution: {integrity: sha512-R0YxRp6/4W7yG1nKbfu41bp3d96a0EalonQXiMe+1H9GTHfKxGNCGFNWUho18avRBPsO8T3RmdWuzmfurlQPbg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@16.0.0': - resolution: {integrity: sha512-hB4GZnJGKa8m4efvTGNyii6qs76vTNl+3dKHTCAUaksN6KjYy4iEO3Q5ira405NW2PKb3EcqWiRaL9DrYJfMHg==} + '@next/swc-darwin-x64@16.0.1': + resolution: {integrity: sha512-kETZBocRux3xITiZtOtVoVvXyQLB7VBxN7L6EPqgI5paZiUlnsgYv4q8diTNYeHmF9EiehydOBo20lTttCbHAg==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@16.0.0': - resolution: {integrity: sha512-E2IHMdE+C1k+nUgndM13/BY/iJY9KGCphCftMh7SXWcaQqExq/pJU/1Hgn8n/tFwSoLoYC/yUghOv97tAsIxqg==} + '@next/swc-linux-arm64-gnu@16.0.1': + resolution: {integrity: sha512-hWg3BtsxQuSKhfe0LunJoqxjO4NEpBmKkE+P2Sroos7yB//OOX3jD5ISP2wv8QdUwtRehMdwYz6VB50mY6hqAg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@16.0.0': - resolution: {integrity: sha512-xzgl7c7BVk4+7PDWldU+On2nlwnGgFqJ1siWp3/8S0KBBLCjonB6zwJYPtl4MUY7YZJrzzumdUpUoquu5zk8vg==} + '@next/swc-linux-arm64-musl@16.0.1': + resolution: {integrity: sha512-UPnOvYg+fjAhP3b1iQStcYPWeBFRLrugEyK/lDKGk7kLNua8t5/DvDbAEFotfV1YfcOY6bru76qN9qnjLoyHCQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-x64-gnu@16.0.0': - resolution: {integrity: sha512-sdyOg4cbiCw7YUr0F/7ya42oiVBXLD21EYkSwN+PhE4csJH4MSXUsYyslliiiBwkM+KsuQH/y9wuxVz6s7Nstg==} + '@next/swc-linux-x64-gnu@16.0.1': + resolution: {integrity: sha512-Et81SdWkcRqAJziIgFtsFyJizHoWne4fzJkvjd6V4wEkWTB4MX6J0uByUb0peiJQ4WeAt6GGmMszE5KrXK6WKg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@16.0.0': - resolution: {integrity: sha512-IAXv3OBYqVaNOgyd3kxR4L3msuhmSy1bcchPHxDOjypG33i2yDWvGBwFD94OuuTjjTt/7cuIKtAmoOOml6kfbg==} + '@next/swc-linux-x64-musl@16.0.1': + resolution: {integrity: sha512-qBbgYEBRrC1egcG03FZaVfVxrJm8wBl7vr8UFKplnxNRprctdP26xEv9nJ07Ggq4y1adwa0nz2mz83CELY7N6Q==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-win32-arm64-msvc@16.0.0': - resolution: {integrity: sha512-bmo3ncIJKUS9PWK1JD9pEVv0yuvp1KPuOsyJTHXTv8KDrEmgV/K+U0C75rl9rhIaODcS7JEb6/7eJhdwXI0XmA==} + '@next/swc-win32-arm64-msvc@16.0.1': + resolution: {integrity: sha512-cPuBjYP6I699/RdbHJonb3BiRNEDm5CKEBuJ6SD8k3oLam2fDRMKAvmrli4QMDgT2ixyRJ0+DTkiODbIQhRkeQ==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-x64-msvc@16.0.0': - resolution: {integrity: sha512-O1cJbT+lZp+cTjYyZGiDwsOjO3UHHzSqobkPNipdlnnuPb1swfcuY6r3p8dsKU4hAIEO4cO67ZCfVVH/M1ETXA==} + '@next/swc-win32-x64-msvc@16.0.1': + resolution: {integrity: sha512-XeEUJsE4JYtfrXe/LaJn3z1pD19fK0Q6Er8Qoufi+HqvdO4LEPyCxLUt4rxA+4RfYo6S9gMlmzCMU2F+AatFqQ==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -4387,85 +4389,85 @@ packages: resolution: {integrity: sha512-Tb5wIMvBf/nLejTQ61krK644/CEMB/cpiaIFXqGApfGqO3GwcR3qnI0DbmkFVCl2OyEp8LnLX3EkucoL0+tbFg==} engines: {node: ^v12.20.0 || ^14.13.0 || >=16.0.0} - '@rolldown/binding-android-arm64@1.0.0-beta.44': - resolution: {integrity: sha512-g9ejDOehJFhxC1DIXQuZQ9bKv4lRDioOTL42cJjFjqKPl1L7DVb9QQQE1FxokGEIMr6FezLipxwnzOXWe7DNPg==} + '@rolldown/binding-android-arm64@1.0.0-beta.45': + resolution: {integrity: sha512-bfgKYhFiXJALeA/riil908+2vlyWGdwa7Ju5S+JgWZYdR4jtiPOGdM6WLfso1dojCh+4ZWeiTwPeV9IKQEX+4g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.0-beta.44': - resolution: {integrity: sha512-PxAW1PXLPmCzfhfKIS53kwpjLGTUdIfX4Ht+l9mj05C3lYCGaGowcNsYi2rdxWH24vSTmeK+ajDNRmmmrK0M7g==} + '@rolldown/binding-darwin-arm64@1.0.0-beta.45': + resolution: {integrity: sha512-xjCv4CRVsSnnIxTuyH1RDJl5OEQ1c9JYOwfDAHddjJDxCw46ZX9q80+xq7Eok7KC4bRSZudMJllkvOKv0T9SeA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-beta.44': - resolution: {integrity: sha512-/CtQqs1oO9uSb5Ju60rZvsdjE7Pzn8EK2ISAdl2jedjMzeD/4neNyCbwyJOAPzU+GIQTZVyrFZJX+t7HXR1R/g==} + '@rolldown/binding-darwin-x64@1.0.0-beta.45': + resolution: {integrity: sha512-ddcO9TD3D/CLUa/l8GO8LHzBOaZqWg5ClMy3jICoxwCuoz47h9dtqPsIeTiB6yR501LQTeDsjA4lIFd7u3Ljfw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.0-beta.44': - resolution: {integrity: sha512-V5Q5W9c4+2GJ4QabmjmVV6alY97zhC/MZBaLkDtHwGy3qwzbM4DYgXUbun/0a8AH5hGhuU27tUIlYz6ZBlvgOA==} + '@rolldown/binding-freebsd-x64@1.0.0-beta.45': + resolution: {integrity: sha512-MBTWdrzW9w+UMYDUvnEuh0pQvLENkl2Sis15fHTfHVW7ClbGuez+RWopZudIDEGkpZXdeI4CkRXk+vdIIebrmg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.44': - resolution: {integrity: sha512-X6adjkHeFqKsTU0FXdNN9HY4LDozPqIfHcnXovE5RkYLWIjMWuc489mIZ6iyhrMbCqMUla9IOsh5dvXSGT9o9A==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.45': + resolution: {integrity: sha512-4YgoCFiki1HR6oSg+GxxfzfnVCesQxLF1LEnw9uXS/MpBmuog0EOO2rYfy69rWP4tFZL9IWp6KEfGZLrZ7aUog==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.44': - resolution: {integrity: sha512-kRRKGZI4DXWa6ANFr3dLA85aSVkwPdgXaRjfanwY84tfc3LncDiIjyWCb042e3ckPzYhHSZ3LmisO+cdOIYL6Q==} + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.45': + resolution: {integrity: sha512-LE1gjAwQRrbCOorJJ7LFr10s5vqYf5a00V5Ea9wXcT2+56n5YosJkcp8eQ12FxRBv2YX8dsdQJb+ZTtYJwb6XQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.44': - resolution: {integrity: sha512-hMtiN9xX1NhxXBa2U3Up4XkVcsVp2h73yYtMDY59z9CDLEZLrik9RVLhBL5QtoX4zZKJ8HZKJtWuGYvtmkCbIQ==} + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.45': + resolution: {integrity: sha512-tdy8ThO/fPp40B81v0YK3QC+KODOmzJzSUOO37DinQxzlTJ026gqUSOM8tzlVixRbQJltgVDCTYF8HNPRErQTA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.44': - resolution: {integrity: sha512-rd1LzbpXQuR8MTG43JB9VyXDjG7ogSJbIkBpZEHJ8oMKzL6j47kQT5BpIXrg3b5UVygW9QCI2fpFdMocT5Kudg==} + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.45': + resolution: {integrity: sha512-lS082ROBWdmOyVY/0YB3JmsiClaWoxvC+dA8/rbhyB9VLkvVEaihLEOr4CYmrMse151C4+S6hCw6oa1iewox7g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@rolldown/binding-linux-x64-musl@1.0.0-beta.44': - resolution: {integrity: sha512-qI2IiPqmPRW25exXkuQr3TlweCDc05YvvbSDRPCuPsWkwb70dTiSoXn8iFxT4PWqTi71wWHg1Wyta9PlVhX5VA==} + '@rolldown/binding-linux-x64-musl@1.0.0-beta.45': + resolution: {integrity: sha512-Hi73aYY0cBkr1/SvNQqH8Cd+rSV6S9RB5izCv0ySBcRnd/Wfn5plguUoGYwBnhHgFbh6cPw9m2dUVBR6BG1gxA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@rolldown/binding-openharmony-arm64@1.0.0-beta.44': - resolution: {integrity: sha512-+vHvEc1pL5iJRFlldLC8mjm6P4Qciyfh2bh5ZI6yxDQKbYhCHRKNURaKz1mFcwxhVL5YMYsLyaqM3qizVif9MQ==} + '@rolldown/binding-openharmony-arm64@1.0.0-beta.45': + resolution: {integrity: sha512-fljEqbO7RHHogNDxYtTzr+GNjlfOx21RUyGmF+NrkebZ8emYYiIqzPxsaMZuRx0rgZmVmliOzEp86/CQFDKhJQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.0-beta.44': - resolution: {integrity: sha512-XSgLxRrtFj6RpTeMYmmQDAwHjKseYGKUn5LPiIdW4Cq+f5SBSStL2ToBDxkbdxKPEbCZptnLPQ/nfKcAxrC8Xg==} + '@rolldown/binding-wasm32-wasi@1.0.0-beta.45': + resolution: {integrity: sha512-ZJDB7lkuZE9XUnWQSYrBObZxczut+8FZ5pdanm8nNS1DAo8zsrPuvGwn+U3fwU98WaiFsNrA4XHngesCGr8tEQ==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.44': - resolution: {integrity: sha512-cF1LJdDIX02cJrFrX3wwQ6IzFM7I74BYeKFkzdcIA4QZ0+2WA7/NsKIgjvrunupepWb1Y6PFWdRlHSaz5AW1Wg==} + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.45': + resolution: {integrity: sha512-zyzAjItHPUmxg6Z8SyRhLdXlJn3/D9KL5b9mObUrBHhWS/GwRH4665xCiFqeuktAhhWutqfc+rOV2LjK4VYQGQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.44': - resolution: {integrity: sha512-5uaJonDafhHiMn+iEh7qUp3QQ4Gihv3lEOxKfN8Vwadpy0e+5o28DWI42DpJ9YBYMrVy4JOWJ/3etB/sptpUwA==} + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.45': + resolution: {integrity: sha512-wODcGzlfxqS6D7BR0srkJk3drPwXYLu7jPHN27ce2c4PUnVVmJnp9mJzUQGT4LpmHmmVdMZ+P6hKvyTGBzc1CA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.44': - resolution: {integrity: sha512-vsqhWAFJkkmgfBN/lkLCWTXF1PuPhMjfnAyru48KvF7mVh2+K7WkKYHezF3Fjz4X/mPScOcIv+g6cf6wnI6eWg==} + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.45': + resolution: {integrity: sha512-wiU40G1nQo9rtfvF9jLbl79lUgjfaD/LTyUEw2Wg/gdF5OhjzpKMVugZQngO+RNdwYaNj+Fs+kWBWfp4VXPMHA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -4473,8 +4475,8 @@ packages: '@rolldown/pluginutils@1.0.0-beta.43': resolution: {integrity: sha512-5Uxg7fQUCmfhax7FJke2+8B6cqgeUJUD9o2uXIKXhD+mG0mL6NObmVoi9wXEU1tY89mZKgAYA6fTbftx3q2ZPQ==} - '@rolldown/pluginutils@1.0.0-beta.44': - resolution: {integrity: sha512-g6eW7Zwnr2c5RADIoqziHoVs6b3W5QTQ4+qbpfjbkMJ9x+8Og211VW/oot2dj9dVwaK/UyC6Yo+02gV+wWQVNg==} + '@rolldown/pluginutils@1.0.0-beta.45': + resolution: {integrity: sha512-Le9ulGCrD8ggInzWw/k2J8QcbPz7eGIOWqfJ2L+1R0Opm7n6J37s2hiDWlh6LJN0Lk9L5sUzMvRHKW7UxBZsQA==} '@rollup/plugin-babel@5.3.1': resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} @@ -4664,32 +4666,32 @@ packages: '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} - '@shikijs/core@3.13.0': - resolution: {integrity: sha512-3P8rGsg2Eh2qIHekwuQjzWhKI4jV97PhvYjYUzGqjvJfqdQPz+nMlfWahU24GZAyW1FxFI1sYjyhfh5CoLmIUA==} + '@shikijs/core@3.14.0': + resolution: {integrity: sha512-qRSeuP5vlYHCNUIrpEBQFO7vSkR7jn7Kv+5X3FO/zBKVDGQbcnlScD3XhkrHi/R8Ltz0kEjvFR9Szp/XMRbFMw==} '@shikijs/core@3.7.0': resolution: {integrity: sha512-yilc0S9HvTPyahHpcum8eonYrQtmGTU0lbtwxhA6jHv4Bm1cAdlPFRCJX4AHebkCm75aKTjjRAW+DezqD1b/cg==} - '@shikijs/engine-javascript@3.13.0': - resolution: {integrity: sha512-Ty7xv32XCp8u0eQt8rItpMs6rU9Ki6LJ1dQOW3V/56PKDcpvfHPnYFbsx5FFUP2Yim34m/UkazidamMNVR4vKg==} + '@shikijs/engine-javascript@3.14.0': + resolution: {integrity: sha512-3v1kAXI2TsWQuwv86cREH/+FK9Pjw3dorVEykzQDhwrZj0lwsHYlfyARaKmn6vr5Gasf8aeVpb8JkzeWspxOLQ==} - '@shikijs/engine-oniguruma@3.13.0': - resolution: {integrity: sha512-O42rBGr4UDSlhT2ZFMxqM7QzIU+IcpoTMzb3W7AlziI1ZF7R8eS2M0yt5Ry35nnnTX/LTLXFPUjRFCIW+Operg==} + '@shikijs/engine-oniguruma@3.14.0': + resolution: {integrity: sha512-TNcYTYMbJyy+ZjzWtt0bG5y4YyMIWC2nyePz+CFMWqm+HnZZyy9SWMgo8Z6KBJVIZnx8XUXS8U2afO6Y0g1Oug==} - '@shikijs/langs@3.13.0': - resolution: {integrity: sha512-672c3WAETDYHwrRP0yLy3W1QYB89Hbpj+pO4KhxK6FzIrDI2FoEXNiNCut6BQmEApYLfuYfpgOZaqbY+E9b8wQ==} + '@shikijs/langs@3.14.0': + resolution: {integrity: sha512-DIB2EQY7yPX1/ZH7lMcwrK5pl+ZkP/xoSpUzg9YC8R+evRCCiSQ7yyrvEyBsMnfZq4eBzLzBlugMyTAf13+pzg==} - '@shikijs/rehype@3.13.0': - resolution: {integrity: sha512-dxvB5gXEpiTI3beGwOPEwxFxQNmUWM4cwOWbvUmL6DnQJGl18/+cCjVHZK2OnasmU0v7SvM39Zh3iliWdwfBDA==} + '@shikijs/rehype@3.14.0': + resolution: {integrity: sha512-In2G6yvT0ZFDqNGbJumd7gEAwtxuaXuchCc0O3qOytIUTlpzs8/D0CQF3wktdfOB6B869eab6Z6EIJr4Td4hQQ==} - '@shikijs/themes@3.13.0': - resolution: {integrity: sha512-Vxw1Nm1/Od8jyA7QuAenaV78BG2nSr3/gCGdBkLpfLscddCkzkL36Q5b67SrLLfvAJTOUzW39x4FHVCFriPVgg==} + '@shikijs/themes@3.14.0': + resolution: {integrity: sha512-fAo/OnfWckNmv4uBoUu6dSlkcBc+SA1xzj5oUSaz5z3KqHtEbUypg/9xxgJARtM6+7RVm0Q6Xnty41xA1ma1IA==} '@shikijs/transformers@3.7.0': resolution: {integrity: sha512-VplaqIMRNsNOorCXJHkbF5S0pT6xm8Z/s7w7OPZLohf8tR93XH0krvUafpNy/ozEylrWuShJF0+ftEB+wFRwGA==} - '@shikijs/types@3.13.0': - resolution: {integrity: sha512-oM9P+NCFri/mmQ8LoFGVfVyemm5Hi27330zuOBp0annwJdKH1kOLndw3zCtAVDehPLg9fKqoEx3Ht/wNZxolfw==} + '@shikijs/types@3.14.0': + resolution: {integrity: sha512-bQGgC6vrY8U/9ObG1Z/vTro+uclbjjD/uG58RvfxKZVD5p9Yc1ka3tVyEFy7BNJLzxuWyHH5NWynP9zZZS59eQ==} '@shikijs/types@3.7.0': resolution: {integrity: sha512-MGaLeaRlSWpnP0XSAum3kP3a8vtcTsITqoEPYdt3lQG3YCdQH4DnEhodkYcNMcU0uW0RffhoD1O3e0vG5eSBBg==} @@ -4712,8 +4714,8 @@ packages: resolution: {integrity: sha512-5imgGUlZL4dW4YWdMYAKLmal9ny/tlenM81QZY7xYyb76z9Z/QOg7oM5Ak9HQl8QfFTlGVWwcMXl+54jroRgEQ==} engines: {node: '>=14.0.0'} - '@smithy/abort-controller@4.2.3': - resolution: {integrity: sha512-xWL9Mf8b7tIFuAlpjKtRPnHrR8XVrwTj5NPYO/QwZPtc0SDLsPxb56V5tzi5yspSMytISHybifez+4jlrx0vkQ==} + '@smithy/abort-controller@4.2.4': + resolution: {integrity: sha512-Z4DUr/AkgyFf1bOThW2HwzREagee0sB5ycl+hDiSZOfRLW8ZgrOjDi6g8mHH19yyU5E2A/64W3z6SMIf5XiUSQ==} engines: {node: '>=18.0.0'} '@smithy/chunked-blob-reader-native@4.2.1': @@ -4724,56 +4726,56 @@ packages: resolution: {integrity: sha512-WmU0TnhEAJLWvfSeMxBNe5xtbselEO8+4wG0NtZeL8oR21WgH1xiO37El+/Y+H/Ie4SCwBy3MxYWmOYaGgZueA==} engines: {node: '>=18.0.0'} - '@smithy/config-resolver@4.4.0': - resolution: {integrity: sha512-Kkmz3Mup2PGp/HNJxhCWkLNdlajJORLSjwkcfrj0E7nu6STAEdcMR1ir5P9/xOmncx8xXfru0fbUYLlZog/cFg==} + '@smithy/config-resolver@4.4.1': + resolution: {integrity: sha512-BciDJ5hkyYEGBBKMbjGB1A/Zq8bYZ41Zo9BMnGdKF6QD1fY4zIkYx6zui/0CHaVGnv6h0iy8y4rnPX9CPCAPyQ==} engines: {node: '>=18.0.0'} - '@smithy/core@3.17.1': - resolution: {integrity: sha512-V4Qc2CIb5McABYfaGiIYLTmo/vwNIK7WXI5aGveBd9UcdhbOMwcvIMxIw/DJj1S9QgOMa/7FBkarMdIC0EOTEQ==} + '@smithy/core@3.17.2': + resolution: {integrity: sha512-n3g4Nl1Te+qGPDbNFAYf+smkRVB+JhFsGy9uJXXZQEufoP4u0r+WLh6KvTDolCswaagysDc/afS1yvb2jnj1gQ==} engines: {node: '>=18.0.0'} - '@smithy/credential-provider-imds@4.2.3': - resolution: {integrity: sha512-hA1MQ/WAHly4SYltJKitEsIDVsNmXcQfYBRv2e+q04fnqtAX5qXaybxy/fhUeAMCnQIdAjaGDb04fMHQefWRhw==} + '@smithy/credential-provider-imds@4.2.4': + resolution: {integrity: sha512-YVNMjhdz2pVto5bRdux7GMs0x1m0Afz3OcQy/4Yf9DH4fWOtroGH7uLvs7ZmDyoBJzLdegtIPpXrpJOZWvUXdw==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-codec@4.2.3': - resolution: {integrity: sha512-rcr0VH0uNoMrtgKuY7sMfyKqbHc4GQaQ6Yp4vwgm+Z6psPuOgL+i/Eo/QWdXRmMinL3EgFM0Z1vkfyPyfzLmjw==} + '@smithy/eventstream-codec@4.2.4': + resolution: {integrity: sha512-aV8blR9RBDKrOlZVgjOdmOibTC2sBXNiT7WA558b4MPdsLTV6sbyc1WIE9QiIuYMJjYtnPLciefoqSW8Gi+MZQ==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-browser@4.2.3': - resolution: {integrity: sha512-EcS0kydOr2qJ3vV45y7nWnTlrPmVIMbUFOZbMG80+e2+xePQISX9DrcbRpVRFTS5Nqz3FiEbDcTCAV0or7bqdw==} + '@smithy/eventstream-serde-browser@4.2.4': + resolution: {integrity: sha512-d5T7ZS3J/r8P/PDjgmCcutmNxnSRvPH1U6iHeXjzI50sMr78GLmFcrczLw33Ap92oEKqa4CLrkAPeSSOqvGdUA==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-config-resolver@4.3.3': - resolution: {integrity: sha512-GewKGZ6lIJ9APjHFqR2cUW+Efp98xLu1KmN0jOWxQ1TN/gx3HTUPVbLciFD8CfScBj2IiKifqh9vYFRRXrYqXA==} + '@smithy/eventstream-serde-config-resolver@4.3.4': + resolution: {integrity: sha512-lxfDT0UuSc1HqltOGsTEAlZ6H29gpfDSdEPTapD5G63RbnYToZ+ezjzdonCCH90j5tRRCw3aLXVbiZaBW3VRVg==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-node@4.2.3': - resolution: {integrity: sha512-uQobOTQq2FapuSOlmGLUeGTpvcBLE5Fc7XjERUSk4dxEi4AhTwuyHYZNAvL4EMUp7lzxxkKDFaJ1GY0ovrj0Kg==} + '@smithy/eventstream-serde-node@4.2.4': + resolution: {integrity: sha512-TPhiGByWnYyzcpU/K3pO5V7QgtXYpE0NaJPEZBCa1Y5jlw5SjqzMSbFiLb+ZkJhqoQc0ImGyVINqnq1ze0ZRcQ==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-universal@4.2.3': - resolution: {integrity: sha512-QIvH/CKOk1BZPz/iwfgbh1SQD5Y0lpaw2kLA8zpLRRtYMPXeYUEWh+moTaJyqDaKlbrB174kB7FSRFiZ735tWw==} + '@smithy/eventstream-serde-universal@4.2.4': + resolution: {integrity: sha512-GNI/IXaY/XBB1SkGBFmbW033uWA0tj085eCxYih0eccUe/PFR7+UBQv9HNDk2fD9TJu7UVsCWsH99TkpEPSOzQ==} engines: {node: '>=18.0.0'} - '@smithy/fetch-http-handler@5.3.4': - resolution: {integrity: sha512-bwigPylvivpRLCm+YK9I5wRIYjFESSVwl8JQ1vVx/XhCw0PtCi558NwTnT2DaVCl5pYlImGuQTSwMsZ+pIavRw==} + '@smithy/fetch-http-handler@5.3.5': + resolution: {integrity: sha512-mg83SM3FLI8Sa2ooTJbsh5MFfyMTyNRwxqpKHmE0ICRIa66Aodv80DMsTQI02xBLVJ0hckwqTRr5IGAbbWuFLQ==} engines: {node: '>=18.0.0'} - '@smithy/hash-blob-browser@4.2.4': - resolution: {integrity: sha512-W7eIxD+rTNsLB/2ynjmbdeP7TgxRXprfvqQxKFEfy9HW2HeD7t+g+KCIrY0pIn/GFjA6/fIpH+JQnfg5TTk76Q==} + '@smithy/hash-blob-browser@4.2.5': + resolution: {integrity: sha512-kCdgjD2J50qAqycYx0imbkA9tPtyQr1i5GwbK/EOUkpBmJGSkJe4mRJm+0F65TUSvvui1HZ5FFGFCND7l8/3WQ==} engines: {node: '>=18.0.0'} - '@smithy/hash-node@4.2.3': - resolution: {integrity: sha512-6+NOdZDbfuU6s1ISp3UOk5Rg953RJ2aBLNLLBEcamLjHAg1Po9Ha7QIB5ZWhdRUVuOUrT8BVFR+O2KIPmw027g==} + '@smithy/hash-node@4.2.4': + resolution: {integrity: sha512-kKU0gVhx/ppVMntvUOZE7WRMFW86HuaxLwvqileBEjL7PoILI8/djoILw3gPQloGVE6O0oOzqafxeNi2KbnUJw==} engines: {node: '>=18.0.0'} - '@smithy/hash-stream-node@4.2.3': - resolution: {integrity: sha512-EXMSa2yiStVII3x/+BIynyOAZlS7dGvI7RFrzXa/XssBgck/7TXJIvnjnCu328GY/VwHDC4VeDyP1S4rqwpYag==} + '@smithy/hash-stream-node@4.2.4': + resolution: {integrity: sha512-amuh2IJiyRfO5MV0X/YFlZMD6banjvjAwKdeJiYGUbId608x+oSNwv3vlyW2Gt6AGAgl3EYAuyYLGRX/xU8npQ==} engines: {node: '>=18.0.0'} - '@smithy/invalid-dependency@4.2.3': - resolution: {integrity: sha512-Cc9W5DwDuebXEDMpOpl4iERo8I0KFjTnomK2RMdhhR87GwrSmUmwMxS4P5JdRf+LsjOdIqumcerwRgYMr/tZ9Q==} + '@smithy/invalid-dependency@4.2.4': + resolution: {integrity: sha512-z6aDLGiHzsMhbS2MjetlIWopWz//K+mCoPXjW6aLr0mypF+Y7qdEh5TyJ20Onf9FbWHiWl4eC+rITdizpnXqOw==} engines: {node: '>=18.0.0'} '@smithy/is-array-buffer@2.2.0': @@ -4784,92 +4786,92 @@ packages: resolution: {integrity: sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==} engines: {node: '>=18.0.0'} - '@smithy/md5-js@4.2.3': - resolution: {integrity: sha512-5+4bUEJQi/NRgzdA5SVXvAwyvEnD0ZAiKzV3yLO6dN5BG8ScKBweZ8mxXXUtdxq+Dx5k6EshKk0XJ7vgvIPSnA==} + '@smithy/md5-js@4.2.4': + resolution: {integrity: sha512-h7kzNWZuMe5bPnZwKxhVbY1gan5+TZ2c9JcVTHCygB14buVGOZxLl+oGfpY2p2Xm48SFqEWdghpvbBdmaz3ncQ==} engines: {node: '>=18.0.0'} - '@smithy/middleware-content-length@4.2.3': - resolution: {integrity: sha512-/atXLsT88GwKtfp5Jr0Ks1CSa4+lB+IgRnkNrrYP0h1wL4swHNb0YONEvTceNKNdZGJsye+W2HH8W7olbcPUeA==} + '@smithy/middleware-content-length@4.2.4': + resolution: {integrity: sha512-hJRZuFS9UsElX4DJSJfoX4M1qXRH+VFiLMUnhsWvtOOUWRNvvOfDaUSdlNbjwv1IkpVjj/Rd/O59Jl3nhAcxow==} engines: {node: '>=18.0.0'} - '@smithy/middleware-endpoint@4.3.5': - resolution: {integrity: sha512-SIzKVTvEudFWJbxAaq7f2GvP3jh2FHDpIFI6/VAf4FOWGFZy0vnYMPSRj8PGYI8Hjt29mvmwSRgKuO3bK4ixDw==} + '@smithy/middleware-endpoint@4.3.6': + resolution: {integrity: sha512-PXehXofGMFpDqr933rxD8RGOcZ0QBAWtuzTgYRAHAL2BnKawHDEdf/TnGpcmfPJGwonhginaaeJIKluEojiF/w==} engines: {node: '>=18.0.0'} - '@smithy/middleware-retry@4.4.5': - resolution: {integrity: sha512-DCaXbQqcZ4tONMvvdz+zccDE21sLcbwWoNqzPLFlZaxt1lDtOE2tlVpRSwcTOJrjJSUThdgEYn7HrX5oLGlK9A==} + '@smithy/middleware-retry@4.4.6': + resolution: {integrity: sha512-OhLx131znrEDxZPAvH/OYufR9d1nB2CQADyYFN4C3V/NQS7Mg4V6uvxHC/Dr96ZQW8IlHJTJ+vAhKt6oxWRndA==} engines: {node: '>=18.0.0'} - '@smithy/middleware-serde@4.2.3': - resolution: {integrity: sha512-8g4NuUINpYccxiCXM5s1/V+uLtts8NcX4+sPEbvYQDZk4XoJfDpq5y2FQxfmUL89syoldpzNzA0R9nhzdtdKnQ==} + '@smithy/middleware-serde@4.2.4': + resolution: {integrity: sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg==} engines: {node: '>=18.0.0'} - '@smithy/middleware-stack@4.2.3': - resolution: {integrity: sha512-iGuOJkH71faPNgOj/gWuEGS6xvQashpLwWB1HjHq1lNNiVfbiJLpZVbhddPuDbx9l4Cgl0vPLq5ltRfSaHfspA==} + '@smithy/middleware-stack@4.2.4': + resolution: {integrity: sha512-Gy3TKCOnm9JwpFooldwAboazw+EFYlC+Bb+1QBsSi5xI0W5lX81j/P5+CXvD/9ZjtYKRgxq+kkqd/KOHflzvgA==} engines: {node: '>=18.0.0'} - '@smithy/node-config-provider@4.3.3': - resolution: {integrity: sha512-NzI1eBpBSViOav8NVy1fqOlSfkLgkUjUTlohUSgAEhHaFWA3XJiLditvavIP7OpvTjDp5u2LhtlBhkBlEisMwA==} + '@smithy/node-config-provider@4.3.4': + resolution: {integrity: sha512-3X3w7qzmo4XNNdPKNS4nbJcGSwiEMsNsRSunMA92S4DJLLIrH5g1AyuOA2XKM9PAPi8mIWfqC+fnfKNsI4KvHw==} engines: {node: '>=18.0.0'} '@smithy/node-http-handler@1.1.0': resolution: {integrity: sha512-d3kRriEgaIiGXLziAM8bjnaLn1fthCJeTLZIwEIpzQqe6yPX0a+yQoLCTyjb2fvdLwkMoG4p7THIIB5cj5lkbg==} engines: {node: '>=14.0.0'} - '@smithy/node-http-handler@4.4.3': - resolution: {integrity: sha512-MAwltrDB0lZB/H6/2M5PIsISSwdI5yIh6DaBB9r0Flo9nx3y0dzl/qTMJPd7tJvPdsx6Ks/cwVzheGNYzXyNbQ==} + '@smithy/node-http-handler@4.4.4': + resolution: {integrity: sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA==} engines: {node: '>=18.0.0'} - '@smithy/property-provider@4.2.3': - resolution: {integrity: sha512-+1EZ+Y+njiefCohjlhyOcy1UNYjT+1PwGFHCxA/gYctjg3DQWAU19WigOXAco/Ql8hZokNehpzLd0/+3uCreqQ==} + '@smithy/property-provider@4.2.4': + resolution: {integrity: sha512-g2DHo08IhxV5GdY3Cpt/jr0mkTlAD39EJKN27Jb5N8Fb5qt8KG39wVKTXiTRCmHHou7lbXR8nKVU14/aRUf86w==} engines: {node: '>=18.0.0'} '@smithy/protocol-http@1.2.0': resolution: {integrity: sha512-GfGfruksi3nXdFok5RhgtOnWe5f6BndzYfmEXISD+5gAGdayFGpjWu5pIqIweTudMtse20bGbc+7MFZXT1Tb8Q==} engines: {node: '>=14.0.0'} - '@smithy/protocol-http@5.3.3': - resolution: {integrity: sha512-Mn7f/1aN2/jecywDcRDvWWWJF4uwg/A0XjFMJtj72DsgHTByfjRltSqcT9NyE9RTdBSN6X1RSXrhn/YWQl8xlw==} + '@smithy/protocol-http@5.3.4': + resolution: {integrity: sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw==} engines: {node: '>=18.0.0'} '@smithy/querystring-builder@1.1.0': resolution: {integrity: sha512-gDEi4LxIGLbdfjrjiY45QNbuDmpkwh9DX4xzrR2AzjjXpxwGyfSpbJaYhXARw9p17VH0h9UewnNQXNwaQyYMDA==} engines: {node: '>=14.0.0'} - '@smithy/querystring-builder@4.2.3': - resolution: {integrity: sha512-LOVCGCmwMahYUM/P0YnU/AlDQFjcu+gWbFJooC417QRB/lDJlWSn8qmPSDp+s4YVAHOgtgbNG4sR+SxF/VOcJQ==} + '@smithy/querystring-builder@4.2.4': + resolution: {integrity: sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig==} engines: {node: '>=18.0.0'} - '@smithy/querystring-parser@4.2.3': - resolution: {integrity: sha512-cYlSNHcTAX/wc1rpblli3aUlLMGgKZ/Oqn8hhjFASXMCXjIqeuQBei0cnq2JR8t4RtU9FpG6uyl6PxyArTiwKA==} + '@smithy/querystring-parser@4.2.4': + resolution: {integrity: sha512-aHb5cqXZocdzEkZ/CvhVjdw5l4r1aU/9iMEyoKzH4eXMowT6M0YjBpp7W/+XjkBnY8Xh0kVd55GKjnPKlCwinQ==} engines: {node: '>=18.0.0'} - '@smithy/service-error-classification@4.2.3': - resolution: {integrity: sha512-NkxsAxFWwsPsQiwFG2MzJ/T7uIR6AQNh1SzcxSUnmmIqIQMlLRQDKhc17M7IYjiuBXhrQRjQTo3CxX+DobS93g==} + '@smithy/service-error-classification@4.2.4': + resolution: {integrity: sha512-fdWuhEx4+jHLGeew9/IvqVU/fxT/ot70tpRGuOLxE3HzZOyKeTQfYeV1oaBXpzi93WOk668hjMuuagJ2/Qs7ng==} engines: {node: '>=18.0.0'} - '@smithy/shared-ini-file-loader@4.3.3': - resolution: {integrity: sha512-9f9Ixej0hFhroOK2TxZfUUDR13WVa8tQzhSzPDgXe5jGL3KmaM9s8XN7RQwqtEypI82q9KHnKS71CJ+q/1xLtQ==} + '@smithy/shared-ini-file-loader@4.3.4': + resolution: {integrity: sha512-y5ozxeQ9omVjbnJo9dtTsdXj9BEvGx2X8xvRgKnV+/7wLBuYJQL6dOa/qMY6omyHi7yjt1OA97jZLoVRYi8lxA==} engines: {node: '>=18.0.0'} - '@smithy/signature-v4@5.3.3': - resolution: {integrity: sha512-CmSlUy+eEYbIEYN5N3vvQTRfqt0lJlQkaQUIf+oizu7BbDut0pozfDjBGecfcfWf7c62Yis4JIEgqQ/TCfodaA==} + '@smithy/signature-v4@5.3.4': + resolution: {integrity: sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A==} engines: {node: '>=18.0.0'} - '@smithy/smithy-client@4.9.1': - resolution: {integrity: sha512-Ngb95ryR5A9xqvQFT5mAmYkCwbXvoLavLFwmi7zVg/IowFPCfiqRfkOKnbc/ZRL8ZKJ4f+Tp6kSu6wjDQb8L/g==} + '@smithy/smithy-client@4.9.2': + resolution: {integrity: sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg==} engines: {node: '>=18.0.0'} '@smithy/types@1.2.0': resolution: {integrity: sha512-z1r00TvBqF3dh4aHhya7nz1HhvCg4TRmw51fjMrh5do3h+ngSstt/yKlNbHeb9QxJmFbmN8KEVSWgb1bRvfEoA==} engines: {node: '>=14.0.0'} - '@smithy/types@4.8.0': - resolution: {integrity: sha512-QpELEHLO8SsQVtqP+MkEgCYTFW0pleGozfs3cZ183ZBj9z3VC1CX1/wtFMK64p+5bhtZo41SeLK1rBRtd25nHQ==} + '@smithy/types@4.8.1': + resolution: {integrity: sha512-N0Zn0OT1zc+NA+UVfkYqQzviRh5ucWwO7mBV3TmHHprMnfcJNfhlPicDkBHi0ewbh+y3evR6cNAW0Raxvb01NA==} engines: {node: '>=18.0.0'} - '@smithy/url-parser@4.2.3': - resolution: {integrity: sha512-I066AigYvY3d9VlU3zG9XzZg1yT10aNqvCaBTw9EPgu5GrsEl1aUkcMvhkIXascYH1A8W0LQo3B1Kr1cJNcQEw==} + '@smithy/url-parser@4.2.4': + resolution: {integrity: sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg==} engines: {node: '>=18.0.0'} '@smithy/util-base64@4.3.0': @@ -4896,32 +4898,32 @@ packages: resolution: {integrity: sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-browser@4.3.4': - resolution: {integrity: sha512-qI5PJSW52rnutos8Bln8nwQZRpyoSRN6k2ajyoUHNMUzmWqHnOJCnDELJuV6m5PML0VkHI+XcXzdB+6awiqYUw==} + '@smithy/util-defaults-mode-browser@4.3.5': + resolution: {integrity: sha512-GwaGjv/QLuL/QHQaqhf/maM7+MnRFQQs7Bsl6FlaeK6lm6U7mV5AAnVabw68cIoMl5FQFyKK62u7RWRzWL25OQ==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-node@4.2.6': - resolution: {integrity: sha512-c6M/ceBTm31YdcFpgfgQAJaw3KbaLuRKnAz91iMWFLSrgxRpYm03c3bu5cpYojNMfkV9arCUelelKA7XQT36SQ==} + '@smithy/util-defaults-mode-node@4.2.7': + resolution: {integrity: sha512-6hinjVqec0WYGsqN7h9hL/ywfULmJJNXGXnNZW7jrIn/cFuC/aVlVaiDfBIJEvKcOrmN8/EgsW69eY0gXABeHw==} engines: {node: '>=18.0.0'} - '@smithy/util-endpoints@3.2.3': - resolution: {integrity: sha512-aCfxUOVv0CzBIkU10TubdgKSx5uRvzH064kaiPEWfNIvKOtNpu642P4FP1hgOFkjQIkDObrfIDnKMKkeyrejvQ==} + '@smithy/util-endpoints@3.2.4': + resolution: {integrity: sha512-f+nBDhgYRCmUEDKEQb6q0aCcOTXRDqH5wWaFHJxt4anB4pKHlgGoYP3xtioKXH64e37ANUkzWf6p4Mnv1M5/Vg==} engines: {node: '>=18.0.0'} '@smithy/util-hex-encoding@4.2.0': resolution: {integrity: sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==} engines: {node: '>=18.0.0'} - '@smithy/util-middleware@4.2.3': - resolution: {integrity: sha512-v5ObKlSe8PWUHCqEiX2fy1gNv6goiw6E5I/PN2aXg3Fb/hse0xeaAnSpXDiWl7x6LamVKq7senB+m5LOYHUAHw==} + '@smithy/util-middleware@4.2.4': + resolution: {integrity: sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg==} engines: {node: '>=18.0.0'} - '@smithy/util-retry@4.2.3': - resolution: {integrity: sha512-lLPWnakjC0q9z+OtiXk+9RPQiYPNAovt2IXD3CP4LkOnd9NpUsxOjMx1SnoUVB7Orb7fZp67cQMtTBKMFDvOGg==} + '@smithy/util-retry@4.2.4': + resolution: {integrity: sha512-yQncJmj4dtv/isTXxRb4AamZHy4QFr4ew8GxS6XLWt7sCIxkPxPzINWd7WLISEFPsIan14zrKgvyAF+/yzfwoA==} engines: {node: '>=18.0.0'} - '@smithy/util-stream@4.5.4': - resolution: {integrity: sha512-+qDxSkiErejw1BAIXUFBSfM5xh3arbz1MmxlbMCKanDDZtVEQ7PSKW9FQS0Vud1eI/kYn0oCTVKyNzRlq+9MUw==} + '@smithy/util-stream@4.5.5': + resolution: {integrity: sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w==} engines: {node: '>=18.0.0'} '@smithy/util-uri-escape@1.1.0': @@ -4940,8 +4942,8 @@ packages: resolution: {integrity: sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==} engines: {node: '>=18.0.0'} - '@smithy/util-waiter@4.2.3': - resolution: {integrity: sha512-5+nU///E5sAdD7t3hs4uwvCTWQtTR8JwKwOCSJtBRx0bY1isDo1QwH87vRK86vlFLBTISqoDA2V6xvP6nF1isQ==} + '@smithy/util-waiter@4.2.4': + resolution: {integrity: sha512-roKXtXIC6fopFvVOju8VYHtguc/jAcMlK8IlDOHsrQn0ayMkHynjm/D2DCMRf7MJFXzjHhlzg2edr3QPEakchQ==} engines: {node: '>=18.0.0'} '@smithy/uuid@1.1.0': @@ -5379,12 +5381,15 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node@20.19.23': - resolution: {integrity: sha512-yIdlVVVHXpmqRhtyovZAcSy0MiPcYWGkoO4CGe/+jpP0hmNuihm4XhHbADpK++MsiLHP5MVlv+bcgdF99kSiFQ==} + '@types/node@20.19.24': + resolution: {integrity: sha512-FE5u0ezmi6y9OZEzlJfg37mqqf6ZDSF2V/NLjUyGrR9uTZ7Sb9F7bLNZ03S4XVUNRWGA7Ck4c1kK+YnuWjl+DA==} '@types/node@24.9.1': resolution: {integrity: sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==} + '@types/node@24.9.2': + resolution: {integrity: sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA==} + '@types/node@8.10.66': resolution: {integrity: sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==} @@ -5403,8 +5408,8 @@ packages: '@types/pg@8.11.6': resolution: {integrity: sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==} - '@types/pg@8.15.5': - resolution: {integrity: sha512-LF7lF6zWEKxuT3/OR8wAZGzkg4ENGXFNyiV/JeOt9z5B+0ZVwbql9McqX5c/WStFq1GaGso7H1AzP/qSzmlCKQ==} + '@types/pg@8.15.6': + resolution: {integrity: sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==} '@types/prismjs@1.26.5': resolution: {integrity: sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==} @@ -5686,8 +5691,8 @@ packages: peerDependencies: react: '>= 16.8.0' - '@uswriting/exiftool@1.0.3': - resolution: {integrity: sha512-dw6LOo7GnG65I9fCCVbsensRaQrATvBhRhuFQsMl21JPB9CCJWrArD4/BaRQkftrjOXLVJ9qqp6/XSgcRKfnkQ==} + '@uswriting/exiftool@1.0.5': + resolution: {integrity: sha512-yrEbljp4BDWizJ1BcZPiDnJShDdpi8GmZwFXpxrH7g2mG49KiToxmhYqu1NBf+rYkh92c/a+BVn+zSDHq1vNVw==} '@vercel/postgres@0.10.0': resolution: {integrity: sha512-fSD23DxGND40IzSkXjcFcxr53t3Tiym59Is0jSYIFpG4/0f0KO9SGtcp1sXiebvPaGe7N/tU05cH4yt2S6/IPg==} @@ -5722,20 +5727,20 @@ packages: peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 - '@vitest/coverage-v8@4.0.3': - resolution: {integrity: sha512-I+MlLwyJRBjmJr1kFYSxoseINbIdpxIAeK10jmXgB0FUtIfdYsvM3lGAvBu5yk8WPyhefzdmbCHCc1idFbNRcg==} + '@vitest/coverage-v8@4.0.6': + resolution: {integrity: sha512-cv6pFXj9/Otk7q1Ocoj8k3BUVVwnFr3jqcqpwYrU5LkKClU9DpaMEdX+zptx/RyIJS+/VpoxMWmfISXchmVDPQ==} peerDependencies: - '@vitest/browser': 4.0.3 - vitest: 4.0.3 + '@vitest/browser': 4.0.6 + vitest: 4.0.6 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@4.0.3': - resolution: {integrity: sha512-v3eSDx/bF25pzar6aEJrrdTXJduEBU3uSGXHslIdGIpJVP8tQQHV6x1ZfzbFQ/bLIomLSbR/2ZCfnaEGkWkiVQ==} + '@vitest/expect@4.0.6': + resolution: {integrity: sha512-5j8UUlBVhOjhj4lR2Nt9sEV8b4WtbcYh8vnfhTNA2Kn5+smtevzjNq+xlBuVhnFGXiyPPNzGrOVvmyHWkS5QGg==} - '@vitest/mocker@4.0.3': - resolution: {integrity: sha512-evZcRspIPbbiJEe748zI2BRu94ThCBE+RkjCpVF8yoVYuTV7hMe+4wLF/7K86r8GwJHSmAPnPbZhpXWWrg1qbA==} + '@vitest/mocker@4.0.6': + resolution: {integrity: sha512-3COEIew5HqdzBFEYN9+u0dT3i/NCwppLnO1HkjGfAP1Vs3vti1Hxm/MvcbC4DAn3Szo1M7M3otiAaT83jvqIjA==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0-0 @@ -5745,20 +5750,20 @@ packages: vite: optional: true - '@vitest/pretty-format@4.0.3': - resolution: {integrity: sha512-N7gly/DRXzxa9w9sbDXwD9QNFYP2hw90LLLGDobPNwiWgyW95GMxsCt29/COIKKh3P7XJICR38PSDePenMBtsw==} + '@vitest/pretty-format@4.0.6': + resolution: {integrity: sha512-4vptgNkLIA1W1Nn5X4x8rLJBzPiJwnPc+awKtfBE5hNMVsoAl/JCCPPzNrbf+L4NKgklsis5Yp2gYa+XAS442g==} - '@vitest/runner@4.0.3': - resolution: {integrity: sha512-1/aK6fPM0lYXWyGKwop2Gbvz1plyTps/HDbIIJXYtJtspHjpXIeB3If07eWpVH4HW7Rmd3Rl+IS/+zEAXrRtXA==} + '@vitest/runner@4.0.6': + resolution: {integrity: sha512-trPk5qpd7Jj+AiLZbV/e+KiiaGXZ8ECsRxtnPnCrJr9OW2mLB72Cb824IXgxVz/mVU3Aj4VebY+tDTPn++j1Og==} - '@vitest/snapshot@4.0.3': - resolution: {integrity: sha512-amnYmvZ5MTjNCP1HZmdeczAPLRD6iOm9+2nMRUGxbe/6sQ0Ymur0NnR9LIrWS8JA3wKE71X25D6ya/3LN9YytA==} + '@vitest/snapshot@4.0.6': + resolution: {integrity: sha512-PaYLt7n2YzuvxhulDDu6c9EosiRuIE+FI2ECKs6yvHyhoga+2TBWI8dwBjs+IeuQaMtZTfioa9tj3uZb7nev1g==} - '@vitest/spy@4.0.3': - resolution: {integrity: sha512-82vVL8Cqz7rbXaNUl35V2G7xeNMAjBdNOVaHbrzznT9BmiCiPOzhf0FhU3eP41nP1bLDm/5wWKZqkG4nyU95DQ==} + '@vitest/spy@4.0.6': + resolution: {integrity: sha512-g9jTUYPV1LtRPRCQfhbMintW7BTQz1n6WXYQYRQ25qkyffA4bjVXjkROokZnv7t07OqfaFKw1lPzqKGk1hmNuQ==} - '@vitest/utils@4.0.3': - resolution: {integrity: sha512-qV6KJkq8W3piW6MDIbGOmn1xhvcW4DuA07alqaQ+vdx7YA49J85pnwnxigZVQFQw3tWnQNRKWwhz5wbP6iv/GQ==} + '@vitest/utils@4.0.6': + resolution: {integrity: sha512-bG43VS3iYKrMIZXBo+y8Pti0O7uNju3KvNn6DrQWhQQKcLavMB+0NZfO1/QBAEbq0MaQ3QjNsnnXlGQvsh0Z6A==} '@volar/language-core@2.4.23': resolution: {integrity: sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ==} @@ -6035,8 +6040,8 @@ packages: resolution: {integrity: sha512-eUmh0ld1AUPKTEmdzwGF9QTSexXAyt9rA1F5zDfW1wUi3okA3Tal4NLdCeFI6aiKpBenQhR6NmK9bW9tBHTGPQ==} engines: {node: '>=20'} - better-auth@1.3.29: - resolution: {integrity: sha512-1va1XZLTQme3DX33PgHqwwVyOJya5H0+ozT6BhOjTnwecC50I75F0OqqTwINq4XZ0+GuD3bl3I55RiFP49jStw==} + better-auth@1.3.34: + resolution: {integrity: sha512-LWA52SlvnUBJRbN8VLSTLILPomZY3zZAiLxVJCeSQ5uVmaIKkMBhERitkfJcXB9RJcfl4uP+3EqKkb6hX1/uiw==} peerDependencies: '@lynx-js/react': '*' '@sveltejs/kit': '*' @@ -6123,16 +6128,8 @@ packages: bytewise@1.1.0: resolution: {integrity: sha512-rHuuseJ9iQ0na6UDhnrRVDh8YnWVlU6xM3VH6q/+yHDeUH2zIhUzP+2/h3LIrhLDBtTqzWpE3p3tP/boefskKQ==} - c12@1.11.2: - resolution: {integrity: sha512-oBs8a4uvSDO9dm8b7OCFW7+dgtVrwmwnrVXYzLm43ta7ep2jCn/0MhoUFygIWtxhyy6+/MG7/agvpY0U1Iemew==} - peerDependencies: - magicast: ^0.3.4 - peerDependenciesMeta: - magicast: - optional: true - - c12@3.3.0: - resolution: {integrity: sha512-K9ZkuyeJQeqLEyqldbYLG3wjqwpw4BVaAqvmxq3GYKK0b1A/yYQdIcJxkzAOWcNVWhJpRXAPfZFueekiY/L8Dw==} + c12@3.3.1: + resolution: {integrity: sha512-LcWQ01LT9tkoUINHgpIOv3mMs+Abv7oVCrtpMRi1PaapVEpWoMga5WuT7/DqFTu7URP9ftbOmimNw1KNIGh9DQ==} peerDependencies: magicast: ^0.3.5 peerDependenciesMeta: @@ -6169,6 +6166,9 @@ packages: caniuse-lite@1.0.30001751: resolution: {integrity: sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==} + caniuse-lite@1.0.30001752: + resolution: {integrity: sha512-vKUk7beoukxE47P5gcVNKkDRzXdVofotshHwfR9vmpeFKxmI5PBpgOMC18LUJUA/DvJ70Y7RveasIBraqsyO/g==} + ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -6218,10 +6218,6 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} - chownr@2.0.0: - resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} - engines: {node: '>=10'} - chroma-js@3.1.2: resolution: {integrity: sha512-IJnETTalXbsLx1eKEgx19d5L6SRM7cH4vINw/99p/M11HCuXGRWL+6YmCm7FWFGIo6dtWuQoQi1dc5yQ7ESIHg==} @@ -6360,8 +6356,8 @@ packages: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} - conventional-changelog-angular@8.0.0: - resolution: {integrity: sha512-CLf+zr6St0wIxos4bmaKHRXWAcsCXrJU6F4VdNDrGRK3B8LDLKoX3zuMV5GhtbGkVR/LohZ6MT6im43vZLSjmA==} + conventional-changelog-angular@8.1.0: + resolution: {integrity: sha512-GGf2Nipn1RUCAktxuVauVr1e3r8QrLP/B0lEUsFktmGqc3ddbQkhoJZHJctVU829U1c6mTSWftrVOCHaL85Q3w==} engines: {node: '>=18'} conventional-changelog-atom@5.0.0: @@ -6417,8 +6413,8 @@ packages: resolution: {integrity: sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q==} engines: {node: '>=18'} - conventional-commits-parser@6.2.0: - resolution: {integrity: sha512-uLnoLeIW4XaoFtH37qEcg/SXMJmKF4vi7V0H2rnPueg+VEtFGA/asSCNTcq4M/GQ6QmlzchAEtOoDTtKqWeHag==} + conventional-commits-parser@6.2.1: + resolution: {integrity: sha512-20pyHgnO40rvfI0NGF/xiEoFMkXDtkF8FwHvk5BokoFoCuTQRI8vrNCNFWUOfuolKJMm1tPCHc8GgYEtr1XRNA==} engines: {node: '>=18'} hasBin: true @@ -6655,8 +6651,8 @@ packages: dagre-d3-es@7.0.11: resolution: {integrity: sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==} - daisyui@5.3.9: - resolution: {integrity: sha512-741x1pGGSGHcrBYtdE7iKbqW1OoiijYdAZ8oJPZR9MhSKLcMBlHjKfN3YlM2/K7t5jd7O0sg4SqkVNPylalRFw==} + daisyui@5.3.10: + resolution: {integrity: sha512-vmjyPmm0hvFhA95KB6uiGmWakziB2pBv6CUcs5Ka/3iMBMn9S+C3SZYx9G9l2JrgTZ1EFn61F/HrPcwaUm2kLQ==} data-view-buffer@1.0.2: resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} @@ -6673,8 +6669,8 @@ packages: dayjs@1.11.13: resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} - dayjs@1.11.18: - resolution: {integrity: sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==} + dayjs@1.11.19: + resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} @@ -6803,8 +6799,8 @@ packages: resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} engines: {node: '>=12'} - drizzle-kit@0.31.5: - resolution: {integrity: sha512-+CHgPFzuoTQTt7cOYCV6MOw2w8vqEn/ap1yv4bpZOWL03u7rlVRQhUY0WYT3rHsgVTXwYQDZaSUJSQrMBUKuWg==} + drizzle-kit@0.31.6: + resolution: {integrity: sha512-/B4e/4pwnx25QwD5xXgdpo1S+077a2VZdosXbItE/oNmUgQwZydGDz9qJYmnQl/b+5IX0rLfwRhrPnroGtrg8Q==} hasBin: true drizzle-orm@0.44.7: @@ -7183,8 +7179,8 @@ packages: peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 - eslint-plugin-react-hooks@7.0.0: - resolution: {integrity: sha512-fNXaOwvKwq2+pXiRpXc825Vd63+KM4DLL40Rtlycb8m7fYpp6efrTp1sa6ZbP/Ap58K2bEKFXRmhURE+CJAQWw==} + eslint-plugin-react-hooks@7.0.1: + resolution: {integrity: sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==} engines: {node: '>=18'} peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 @@ -7343,17 +7339,17 @@ packages: resolution: {integrity: sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==} engines: {node: ^18.19.0 || >=20.5.0} - exiftool-vendored.exe@13.38.0: - resolution: {integrity: sha512-oZx5enTAvSiIAXL+OEk7nNWrfUhEdKUpaGwDjCmz4VKwOa4HbisqyM808xPGPYj8X7XikcME/fq5hvevPeE3cw==} + exiftool-vendored.exe@13.40.0: + resolution: {integrity: sha512-OUdoQ2RczAYS+6wdg2hUFjhKoBDXot3PNsmievN1ZspdQVllJF847WUHGpaXJv4QZcDvK9eGKop0vfa62dNwuA==} os: [win32] - exiftool-vendored.pl@13.38.0: - resolution: {integrity: sha512-Q3xl1nnwswrsR5344z4NyqvI74fKwla+VJHY1N+32gcDgt8cs9KBsDUwcNzKHSOSa/MjEfniuCJVrQiqR05iag==} + exiftool-vendored.pl@13.40.0: + resolution: {integrity: sha512-AsCGDXhboDVk8Gkisw+x8JMou1vWeLFH30NX6o2sGgSUKVz0KV5F6AK/d9iO9DHtOYVx6Wt+RbYmAAiCzIxHuQ==} os: ['!win32'] hasBin: true - exiftool-vendored@31.1.0: - resolution: {integrity: sha512-q8StxLawHLDvhqv/uoBYCfVbDskn49Cr5ouNCZhh4lgryGu1aymHwK9AvO6RcW2SbPm5MSnQDJOfGp2MW5Nnrw==} + exiftool-vendored@31.2.0: + resolution: {integrity: sha512-QASA/BEOCXuRlnlqnSdbluRIAW4/BVRFLrxDDAUooi7BP17UDi5F4LHnxENHU/pNNoUx3f3mCehB43aVbkR9xw==} engines: {node: '>=20.0.0'} expect-type@1.2.2: @@ -7516,10 +7512,6 @@ packages: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} - fs-minipass@2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} - fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -7606,10 +7598,6 @@ packages: resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} engines: {node: '>=0.10.0'} - giget@1.2.5: - resolution: {integrity: sha512-r1ekGw/Bgpi3HLV3h1MRBIlSAdHoIMklpaQ3OQLFcRw9PwAj2rqigvIbg+dBUI51OxVI2jsEtDywDBjSiuf7Ug==} - hasBin: true - giget@2.0.0: resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} hasBin: true @@ -7790,8 +7778,8 @@ packages: hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} - hono@4.10.2: - resolution: {integrity: sha512-p6fyzl+mQo6uhESLxbF5WlBOAJMDh36PljwlKtP5V1v09NxlqGru3ShK+4wKhSuhuYf8qxMmrivHOa/M7q0sMg==} + hono@4.10.4: + resolution: {integrity: sha512-YG/fo7zlU3KwrBL5vDpWKisLYiM+nVstBQqfr7gCPbSYURnNEP9BDxEMz8KfsDR9JX0lJWDRNc6nXX31v7ZEyg==} engines: {node: '>=16.9.0'} hookable@5.5.3: @@ -7863,8 +7851,8 @@ packages: resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} - immer@10.1.3: - resolution: {integrity: sha512-tmjF/k8QDKydUlm3mZU+tjM6zeq9/fFpPqH9SzWmBnVVKsPBg/V66qsMwb3/Bo90cgUN+ghdVBess+hPsxUyRw==} + immer@10.2.0: + resolution: {integrity: sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==} import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} @@ -8136,10 +8124,6 @@ packages: engines: {node: '>=10'} hasBin: true - jiti@1.21.7: - resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} - hasBin: true - jiti@2.6.1: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true @@ -8478,8 +8462,8 @@ packages: peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 - lucide-react@0.547.0: - resolution: {integrity: sha512-YLChGBWKq8ynr1UWP8WWRPhHhyuBAXfSBnHSgfoj51L//9TU3d0zvxpigf5C1IJ4vnEoTzthl5awPK55PiZhdA==} + lucide-react@0.552.0: + resolution: {integrity: sha512-g9WCjmfwqbexSnZE+2cl21PCfXOcqnGeWeMTNAOGEfpPbm/ZF4YIq77Z8qWrxbu660EKuLB4nSLggoKnCb+isw==} peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -8510,8 +8494,8 @@ packages: mapbox-gl@3.13.0: resolution: {integrity: sha512-TSSJIvDKsiSPk22889FWk9V4mmjljbizUf8Y2Jhho2j0Mj4zonC6kKwoVLf3oGqYWTZ+oQrd0Cxg6LCmZmPPbQ==} - maplibre-gl@5.9.0: - resolution: {integrity: sha512-YxW9glb/YrDXGDhqy1u+aG113+L86ttAUpTd6sCkGHyUKMXOX8qbGHJQVqxOczy+4CtRKnqcCfSura2MzB0nQA==} + maplibre-gl@5.10.0: + resolution: {integrity: sha512-eLhlX8Fnpaoo7+uGqggZmXmZld6WrbzOJUPB7G8JB8XpminlTnrQTtXilMHduR8fsNVxrzD8yRRqEoajONc8LQ==} engines: {node: '>=16.14.0', npm: '>=8.1.0'} markdown-extensions@2.0.0: @@ -8754,31 +8738,14 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@3.3.6: - resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} - engines: {node: '>=8'} - - minipass@5.0.0: - resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} - engines: {node: '>=8'} - minipass@7.1.2: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} - minizlib@2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} - mixin-deep@1.3.2: resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} engines: {node: '>=0.10.0'} - mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - mlly@1.8.0: resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} @@ -8844,10 +8811,6 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - nbump@2.1.7: - resolution: {integrity: sha512-jXqoeazfaG3VCFsYFZ3NzHfDe2ZR+XWxj0XV5SAWNR339GxE5mNsZtfxe3k2l04QxcGP5IidSPO5d2AsXnOvbQ==} - hasBin: true - nbump@2.1.8: resolution: {integrity: sha512-xbqzRVnGPNCVHBi4+0qrm1jSpZPZ1uZaJrYt/JAvnhf2WDeELGvDxdcqL9fn9ExlwU4g7K9GjdG7gVI794bceg==} hasBin: true @@ -8861,8 +8824,8 @@ packages: react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc - next@16.0.0: - resolution: {integrity: sha512-nYohiNdxGu4OmBzggxy9rczmjIGI+TpR5vbKTsE1HqYwNm1B+YSiugSrFguX6omMOKnDHAmBPY4+8TNJk0Idyg==} + next@16.0.1: + resolution: {integrity: sha512-e9RLSssZwd35p7/vOa+hoDFggUZIUbZhIUSLZuETCwrCVvxOs87NamoUzT+vbcNAL8Ld9GobBnWOA6SbV/arOw==} engines: {node: '>=20.9.0'} hasBin: true peerDependencies: @@ -8928,11 +8891,6 @@ packages: numeral@2.0.6: resolution: {integrity: sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA==} - nypm@0.5.4: - resolution: {integrity: sha512-X0SNNrZiGU8/e/zAB7sCTtdxWTMSIO73q+xuKgglm2Yvzwlo8UoC5FNySQFCvl84uPaeADkqHUZUkWy4aH4xOA==} - engines: {node: ^14.16.0 || >=16.10.0} - hasBin: true - nypm@0.6.2: resolution: {integrity: sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g==} engines: {node: ^14.16.0 || >=16.10.0} @@ -8957,11 +8915,8 @@ packages: obuf@1.1.2: resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} - ofetch@1.4.1: - resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==} - - ohash@1.1.6: - resolution: {integrity: sha512-TBu7PtV8YkAZn0tSxobKY2n2aAQva936lhRrj6957aDaCf9IEtqsKbgMzXE/F/sjqYOwmrukeORHNLe5glk7Cg==} + ofetch@1.5.0: + resolution: {integrity: sha512-A7llJ7eZyziA5xq9//3ZurA8OhFqtS99K5/V1sLBJ5j137CM/OAjlbA/TEJXBuOWwOfLqih+oH5U3ran4za1FQ==} ohash@2.0.11: resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} @@ -9089,9 +9044,6 @@ packages: pathe@0.2.0: resolution: {integrity: sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==} - pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} @@ -9103,9 +9055,6 @@ packages: resolution: {integrity: sha512-SuLdBvS42z33m8ejRbInMapQe8n0D3vN/Xd5fmWM3tufNgRQFBpaW2YVJxQZV4iPNqb0vEFvssMEo5w9c6BTIA==} hasBin: true - perfect-debounce@1.0.0: - resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} - perfect-debounce@2.0.0: resolution: {integrity: sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==} @@ -9410,9 +9359,9 @@ packages: pvtsutils@1.3.6: resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} - pvutils@1.1.3: - resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==} - engines: {node: '>=6.0.0'} + pvutils@1.1.5: + resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} + engines: {node: '>=16.0.0'} quansync@0.2.11: resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} @@ -9488,8 +9437,8 @@ packages: react: '>=16.11.0' react-dom: '>=16.11.0' - rc-field-form@2.7.0: - resolution: {integrity: sha512-hgKsCay2taxzVnBPZl+1n4ZondsV78G++XVsMIJCAoioMjlMQR9YwAp7JZDIECzIu2Z66R+f4SFIRrO2DjDNAA==} + rc-field-form@2.7.1: + resolution: {integrity: sha512-vKeSifSJ6HoLaAB+B8aq/Qgm8a3dyxROzCtKNCsBQgiverpc4kWDQihoUwzUj+zNWJOykwSY4dNX3QrGwtVb9A==} engines: {node: '>=8.x'} peerDependencies: react: '>=16.9.0' @@ -9766,8 +9715,8 @@ packages: react: '>=16.8.0' react-dom: '>=16.8.0' - react-i18next@16.2.0: - resolution: {integrity: sha512-giCEDa6NtQYvuLGW9xaBo4HCVxT0Y8jrOpX/uSnd+lZ3Dmm/2BNrGNEgRZzWDkSobmE6IWPJ+/Ow9Rhi/gP6+g==} + react-i18next@16.2.3: + resolution: {integrity: sha512-O0t2zvmIz7nHWKNfIL+O/NTIbpTaOPY0vZov779hegbep3IZ+xcqkeVPKWBSXwzdkiv77q8zmq9toKIUys1x3A==} peerDependencies: i18next: '>= 25.5.2' react: '>= 16.8.0' @@ -9787,8 +9736,8 @@ packages: peerDependencies: react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-intersection-observer@9.16.0: - resolution: {integrity: sha512-w9nJSEp+DrW9KmQmeWHQyfaP6b03v+TdXynaoA964Wxt7mdR3An11z4NNCQgL4gKSK7y1ver2Fq+JKH6CWEzUA==} + react-intersection-observer@10.0.0: + resolution: {integrity: sha512-JJRgcnFQoVXmbE5+GXr1OS1NDD1gHk0HyfpLcRf0575IbJz+io8yzs4mWVlfaqOQq1FiVjLvuYAdEEcrrCfveg==} peerDependencies: react: ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -9880,8 +9829,8 @@ packages: peerDependencies: react: '>=16.8' - react-router@7.9.4: - resolution: {integrity: sha512-SD3G8HKviFHg9xj7dNODUKDFgpG4xqD5nhyd0mYoB5iISepuZAvzSr8ywxgxKJ52yRzf/HWtVHc9AWwoTbljvA==} + react-router@7.9.5: + resolution: {integrity: sha512-JmxqrnBZ6E9hWmf02jzNn9Jm3UqyeimyiwzD69NjxGySG6lIz/1LVPsoTCwN7NBX2XjCEa1LIX5EMz1j2b6u6A==} engines: {node: '>=20.0.0'} peerDependencies: react: '>=18' @@ -10140,13 +10089,13 @@ packages: robust-predicates@3.0.2: resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} - rolldown-plugin-dts@0.16.12: - resolution: {integrity: sha512-9dGjm5oqtKcbZNhpzyBgb8KrYiU616A7IqcFWG7Msp1RKAXQ/hapjivRg+g5IYWSiFhnk3OKYV5T4Ft1t8Cczg==} + rolldown-plugin-dts@0.17.3: + resolution: {integrity: sha512-8mGnNUVNrqEdTnrlcaDxs4sAZg0No6njO+FuhQd4L56nUbJO1tHxOoKDH3mmMJg7f/BhEj/1KjU5W9kZ9zM/kQ==} engines: {node: '>=20.18.0'} peerDependencies: '@ts-macro/tsc': ^0.3.6 '@typescript/native-preview': '>=7.0.0-dev.20250601.1' - rolldown: ^1.0.0-beta.9 + rolldown: ^1.0.0-beta.44 typescript: ^5.0.0 vue-tsc: ~3.1.0 peerDependenciesMeta: @@ -10159,8 +10108,8 @@ packages: vue-tsc: optional: true - rolldown@1.0.0-beta.44: - resolution: {integrity: sha512-gcqgyCi3g93Fhr49PKvymE8PoaGS0sf6ajQrsYaQ8o5de6aUEbD6rJZiJbhOfpcqOnycgsAsUNPYri1h25NgsQ==} + rolldown@1.0.0-beta.45: + resolution: {integrity: sha512-iMmuD72XXLf26Tqrv1cryNYLX6NNPLhZ3AmNkSf8+xda0H+yijjGJ+wVT9UdBUHOpKzq9RjKtQKRCWoEKQQBZQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -10256,8 +10205,8 @@ packages: server-only@0.0.1: resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==} - set-cookie-parser@2.7.1: - resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} + set-cookie-parser@2.7.2: + resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} @@ -10299,8 +10248,8 @@ packages: resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} engines: {node: '>= 0.4'} - shiki@3.13.0: - resolution: {integrity: sha512-aZW4l8Og16CokuCLf8CF8kq+KK2yOygapU5m3+hoGw0Mdosc6fPitjM+ujYarppj5ZIKGyPDPP1vqmQhr+5/0g==} + shiki@3.14.0: + resolution: {integrity: sha512-J0yvpLI7LSig3Z3acIuDLouV5UCKQqu8qOArwMx+/yPVC3WRMgrP67beaG8F+j4xfEWE0eVC4GeBCIXeOPra1g==} side-channel-list@1.0.0: resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} @@ -10669,10 +10618,6 @@ packages: resolution: {integrity: sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==} engines: {node: '>=6'} - tar@6.2.1: - resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} - engines: {node: '>=10'} - temp-dir@2.0.0: resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} engines: {node: '>=8'} @@ -10803,8 +10748,8 @@ packages: typescript: optional: true - tsdown@0.15.9: - resolution: {integrity: sha512-C0EJYpXIYdlJokTumIL4lmv/wEiB20oa6iiYsXFE7Q0VKF3Ju6TQ7XAn4JQdm+2iQGEfl8cnEKcX5DB7iVR5Dw==} + tsdown@0.15.12: + resolution: {integrity: sha512-c8VLlQm8/lFrOAg5VMVeN4NAbejZyVQkzd+ErjuaQgJFI/9MhR9ivr0H/CM7UlOF1+ELlF6YaI7sU/4itgGQ8w==} engines: {node: '>=20.19.0'} hasBin: true peerDependencies: @@ -10813,6 +10758,7 @@ packages: typescript: ^5.0.0 unplugin-lightningcss: ^0.4.0 unplugin-unused: ^0.5.0 + unrun: ^0.2.1 peerDependenciesMeta: '@arethetypeswrong/core': optional: true @@ -10824,6 +10770,8 @@ packages: optional: true unplugin-unused: optional: true + unrun: + optional: true tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} @@ -11273,18 +11221,18 @@ packages: yaml: optional: true - vitest@4.0.3: - resolution: {integrity: sha512-IUSop8jgaT7w0g1yOM/35qVtKjr/8Va4PrjzH1OUb0YH4c3OXB2lCZDkMAB6glA8T5w8S164oJGsbcmAecr4sA==} + vitest@4.0.6: + resolution: {integrity: sha512-gR7INfiVRwnEOkCk47faros/9McCZMp5LM+OMNWGLaDBSvJxIzwjgNFufkuePBNaesGRnLmNfW+ddbUJRZn0nQ==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/debug': ^4.1.12 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.0.3 - '@vitest/browser-preview': 4.0.3 - '@vitest/browser-webdriverio': 4.0.3 - '@vitest/ui': 4.0.3 + '@vitest/browser-playwright': 4.0.6 + '@vitest/browser-preview': 4.0.6 + '@vitest/browser-webdriverio': 4.0.6 + '@vitest/ui': 4.0.6 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -11553,8 +11501,8 @@ packages: zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - zx@8.8.2: - resolution: {integrity: sha512-JuCw+diiuDihAtDC/ClDjaP3spsOxfFAMWrSa+esdU+YnBwYGuFef+B127zQ3x2FHOFULQ4NbaX/95d5260eYQ==} + zx@8.8.5: + resolution: {integrity: sha512-SNgDF5L0gfN7FwVOdEFguY3orU5AkfFZm9B5YSHog/UDHv+lvmd82ZAsOenOkQixigwH2+yyH198AwNdKhj+RA==} engines: {node: '>= 12.17.0'} hasBin: true @@ -11642,20 +11590,20 @@ snapshots: '@aws-crypto/crc32@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.914.0 + '@aws-sdk/types': 3.921.0 tslib: 2.8.1 '@aws-crypto/crc32c@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.914.0 + '@aws-sdk/types': 3.921.0 tslib: 2.8.1 '@aws-crypto/sha1-browser@5.2.0': dependencies: '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.914.0 + '@aws-sdk/types': 3.921.0 '@aws-sdk/util-locate-window': 3.893.0 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 @@ -11665,7 +11613,7 @@ snapshots: '@aws-crypto/sha256-js': 5.2.0 '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.914.0 + '@aws-sdk/types': 3.921.0 '@aws-sdk/util-locate-window': 3.893.0 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 @@ -11673,7 +11621,7 @@ snapshots: '@aws-crypto/sha256-js@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.914.0 + '@aws-sdk/types': 3.921.0 tslib: 2.8.1 '@aws-crypto/supports-web-crypto@5.2.0': @@ -11682,352 +11630,352 @@ snapshots: '@aws-crypto/util@5.2.0': dependencies: - '@aws-sdk/types': 3.914.0 + '@aws-sdk/types': 3.921.0 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 - '@aws-sdk/client-s3@3.916.0': + '@aws-sdk/client-s3@3.921.0': dependencies: '@aws-crypto/sha1-browser': 5.2.0 '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.916.0 - '@aws-sdk/credential-provider-node': 3.916.0 - '@aws-sdk/middleware-bucket-endpoint': 3.914.0 - '@aws-sdk/middleware-expect-continue': 3.916.0 - '@aws-sdk/middleware-flexible-checksums': 3.916.0 - '@aws-sdk/middleware-host-header': 3.914.0 - '@aws-sdk/middleware-location-constraint': 3.914.0 - '@aws-sdk/middleware-logger': 3.914.0 - '@aws-sdk/middleware-recursion-detection': 3.914.0 - '@aws-sdk/middleware-sdk-s3': 3.916.0 - '@aws-sdk/middleware-ssec': 3.914.0 - '@aws-sdk/middleware-user-agent': 3.916.0 - '@aws-sdk/region-config-resolver': 3.914.0 - '@aws-sdk/signature-v4-multi-region': 3.916.0 - '@aws-sdk/types': 3.914.0 - '@aws-sdk/util-endpoints': 3.916.0 - '@aws-sdk/util-user-agent-browser': 3.914.0 - '@aws-sdk/util-user-agent-node': 3.916.0 - '@aws-sdk/xml-builder': 3.914.0 - '@smithy/config-resolver': 4.4.0 - '@smithy/core': 3.17.1 - '@smithy/eventstream-serde-browser': 4.2.3 - '@smithy/eventstream-serde-config-resolver': 4.3.3 - '@smithy/eventstream-serde-node': 4.2.3 - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/hash-blob-browser': 4.2.4 - '@smithy/hash-node': 4.2.3 - '@smithy/hash-stream-node': 4.2.3 - '@smithy/invalid-dependency': 4.2.3 - '@smithy/md5-js': 4.2.3 - '@smithy/middleware-content-length': 4.2.3 - '@smithy/middleware-endpoint': 4.3.5 - '@smithy/middleware-retry': 4.4.5 - '@smithy/middleware-serde': 4.2.3 - '@smithy/middleware-stack': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/node-http-handler': 4.4.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.1 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 + '@aws-sdk/core': 3.921.0 + '@aws-sdk/credential-provider-node': 3.921.0 + '@aws-sdk/middleware-bucket-endpoint': 3.921.0 + '@aws-sdk/middleware-expect-continue': 3.921.0 + '@aws-sdk/middleware-flexible-checksums': 3.921.0 + '@aws-sdk/middleware-host-header': 3.921.0 + '@aws-sdk/middleware-location-constraint': 3.921.0 + '@aws-sdk/middleware-logger': 3.921.0 + '@aws-sdk/middleware-recursion-detection': 3.921.0 + '@aws-sdk/middleware-sdk-s3': 3.921.0 + '@aws-sdk/middleware-ssec': 3.921.0 + '@aws-sdk/middleware-user-agent': 3.921.0 + '@aws-sdk/region-config-resolver': 3.921.0 + '@aws-sdk/signature-v4-multi-region': 3.921.0 + '@aws-sdk/types': 3.921.0 + '@aws-sdk/util-endpoints': 3.921.0 + '@aws-sdk/util-user-agent-browser': 3.921.0 + '@aws-sdk/util-user-agent-node': 3.921.0 + '@aws-sdk/xml-builder': 3.921.0 + '@smithy/config-resolver': 4.4.1 + '@smithy/core': 3.17.2 + '@smithy/eventstream-serde-browser': 4.2.4 + '@smithy/eventstream-serde-config-resolver': 4.3.4 + '@smithy/eventstream-serde-node': 4.2.4 + '@smithy/fetch-http-handler': 5.3.5 + '@smithy/hash-blob-browser': 4.2.5 + '@smithy/hash-node': 4.2.4 + '@smithy/hash-stream-node': 4.2.4 + '@smithy/invalid-dependency': 4.2.4 + '@smithy/md5-js': 4.2.4 + '@smithy/middleware-content-length': 4.2.4 + '@smithy/middleware-endpoint': 4.3.6 + '@smithy/middleware-retry': 4.4.6 + '@smithy/middleware-serde': 4.2.4 + '@smithy/middleware-stack': 4.2.4 + '@smithy/node-config-provider': 4.3.4 + '@smithy/node-http-handler': 4.4.4 + '@smithy/protocol-http': 5.3.4 + '@smithy/smithy-client': 4.9.2 + '@smithy/types': 4.8.1 + '@smithy/url-parser': 4.2.4 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.4 - '@smithy/util-defaults-mode-node': 4.2.6 - '@smithy/util-endpoints': 3.2.3 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-retry': 4.2.3 - '@smithy/util-stream': 4.5.4 + '@smithy/util-defaults-mode-browser': 4.3.5 + '@smithy/util-defaults-mode-node': 4.2.7 + '@smithy/util-endpoints': 3.2.4 + '@smithy/util-middleware': 4.2.4 + '@smithy/util-retry': 4.2.4 + '@smithy/util-stream': 4.5.5 '@smithy/util-utf8': 4.2.0 - '@smithy/util-waiter': 4.2.3 + '@smithy/util-waiter': 4.2.4 '@smithy/uuid': 1.1.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sso@3.916.0': + '@aws-sdk/client-sso@3.921.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.916.0 - '@aws-sdk/middleware-host-header': 3.914.0 - '@aws-sdk/middleware-logger': 3.914.0 - '@aws-sdk/middleware-recursion-detection': 3.914.0 - '@aws-sdk/middleware-user-agent': 3.916.0 - '@aws-sdk/region-config-resolver': 3.914.0 - '@aws-sdk/types': 3.914.0 - '@aws-sdk/util-endpoints': 3.916.0 - '@aws-sdk/util-user-agent-browser': 3.914.0 - '@aws-sdk/util-user-agent-node': 3.916.0 - '@smithy/config-resolver': 4.4.0 - '@smithy/core': 3.17.1 - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/hash-node': 4.2.3 - '@smithy/invalid-dependency': 4.2.3 - '@smithy/middleware-content-length': 4.2.3 - '@smithy/middleware-endpoint': 4.3.5 - '@smithy/middleware-retry': 4.4.5 - '@smithy/middleware-serde': 4.2.3 - '@smithy/middleware-stack': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/node-http-handler': 4.4.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.1 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 + '@aws-sdk/core': 3.921.0 + '@aws-sdk/middleware-host-header': 3.921.0 + '@aws-sdk/middleware-logger': 3.921.0 + '@aws-sdk/middleware-recursion-detection': 3.921.0 + '@aws-sdk/middleware-user-agent': 3.921.0 + '@aws-sdk/region-config-resolver': 3.921.0 + '@aws-sdk/types': 3.921.0 + '@aws-sdk/util-endpoints': 3.921.0 + '@aws-sdk/util-user-agent-browser': 3.921.0 + '@aws-sdk/util-user-agent-node': 3.921.0 + '@smithy/config-resolver': 4.4.1 + '@smithy/core': 3.17.2 + '@smithy/fetch-http-handler': 5.3.5 + '@smithy/hash-node': 4.2.4 + '@smithy/invalid-dependency': 4.2.4 + '@smithy/middleware-content-length': 4.2.4 + '@smithy/middleware-endpoint': 4.3.6 + '@smithy/middleware-retry': 4.4.6 + '@smithy/middleware-serde': 4.2.4 + '@smithy/middleware-stack': 4.2.4 + '@smithy/node-config-provider': 4.3.4 + '@smithy/node-http-handler': 4.4.4 + '@smithy/protocol-http': 5.3.4 + '@smithy/smithy-client': 4.9.2 + '@smithy/types': 4.8.1 + '@smithy/url-parser': 4.2.4 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.4 - '@smithy/util-defaults-mode-node': 4.2.6 - '@smithy/util-endpoints': 3.2.3 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-retry': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.5 + '@smithy/util-defaults-mode-node': 4.2.7 + '@smithy/util-endpoints': 3.2.4 + '@smithy/util-middleware': 4.2.4 + '@smithy/util-retry': 4.2.4 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/core@3.916.0': + '@aws-sdk/core@3.921.0': dependencies: - '@aws-sdk/types': 3.914.0 - '@aws-sdk/xml-builder': 3.914.0 - '@smithy/core': 3.17.1 - '@smithy/node-config-provider': 4.3.3 - '@smithy/property-provider': 4.2.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/signature-v4': 5.3.3 - '@smithy/smithy-client': 4.9.1 - '@smithy/types': 4.8.0 + '@aws-sdk/types': 3.921.0 + '@aws-sdk/xml-builder': 3.921.0 + '@smithy/core': 3.17.2 + '@smithy/node-config-provider': 4.3.4 + '@smithy/property-provider': 4.2.4 + '@smithy/protocol-http': 5.3.4 + '@smithy/signature-v4': 5.3.4 + '@smithy/smithy-client': 4.9.2 + '@smithy/types': 4.8.1 '@smithy/util-base64': 4.3.0 - '@smithy/util-middleware': 4.2.3 + '@smithy/util-middleware': 4.2.4 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@aws-sdk/credential-provider-env@3.916.0': + '@aws-sdk/credential-provider-env@3.921.0': dependencies: - '@aws-sdk/core': 3.916.0 - '@aws-sdk/types': 3.914.0 - '@smithy/property-provider': 4.2.3 - '@smithy/types': 4.8.0 + '@aws-sdk/core': 3.921.0 + '@aws-sdk/types': 3.921.0 + '@smithy/property-provider': 4.2.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-http@3.916.0': + '@aws-sdk/credential-provider-http@3.921.0': dependencies: - '@aws-sdk/core': 3.916.0 - '@aws-sdk/types': 3.914.0 - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/node-http-handler': 4.4.3 - '@smithy/property-provider': 4.2.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.1 - '@smithy/types': 4.8.0 - '@smithy/util-stream': 4.5.4 + '@aws-sdk/core': 3.921.0 + '@aws-sdk/types': 3.921.0 + '@smithy/fetch-http-handler': 5.3.5 + '@smithy/node-http-handler': 4.4.4 + '@smithy/property-provider': 4.2.4 + '@smithy/protocol-http': 5.3.4 + '@smithy/smithy-client': 4.9.2 + '@smithy/types': 4.8.1 + '@smithy/util-stream': 4.5.5 tslib: 2.8.1 - '@aws-sdk/credential-provider-ini@3.916.0': + '@aws-sdk/credential-provider-ini@3.921.0': dependencies: - '@aws-sdk/core': 3.916.0 - '@aws-sdk/credential-provider-env': 3.916.0 - '@aws-sdk/credential-provider-http': 3.916.0 - '@aws-sdk/credential-provider-process': 3.916.0 - '@aws-sdk/credential-provider-sso': 3.916.0 - '@aws-sdk/credential-provider-web-identity': 3.916.0 - '@aws-sdk/nested-clients': 3.916.0 - '@aws-sdk/types': 3.914.0 - '@smithy/credential-provider-imds': 4.2.3 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/core': 3.921.0 + '@aws-sdk/credential-provider-env': 3.921.0 + '@aws-sdk/credential-provider-http': 3.921.0 + '@aws-sdk/credential-provider-process': 3.921.0 + '@aws-sdk/credential-provider-sso': 3.921.0 + '@aws-sdk/credential-provider-web-identity': 3.921.0 + '@aws-sdk/nested-clients': 3.921.0 + '@aws-sdk/types': 3.921.0 + '@smithy/credential-provider-imds': 4.2.4 + '@smithy/property-provider': 4.2.4 + '@smithy/shared-ini-file-loader': 4.3.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-node@3.916.0': + '@aws-sdk/credential-provider-node@3.921.0': dependencies: - '@aws-sdk/credential-provider-env': 3.916.0 - '@aws-sdk/credential-provider-http': 3.916.0 - '@aws-sdk/credential-provider-ini': 3.916.0 - '@aws-sdk/credential-provider-process': 3.916.0 - '@aws-sdk/credential-provider-sso': 3.916.0 - '@aws-sdk/credential-provider-web-identity': 3.916.0 - '@aws-sdk/types': 3.914.0 - '@smithy/credential-provider-imds': 4.2.3 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/credential-provider-env': 3.921.0 + '@aws-sdk/credential-provider-http': 3.921.0 + '@aws-sdk/credential-provider-ini': 3.921.0 + '@aws-sdk/credential-provider-process': 3.921.0 + '@aws-sdk/credential-provider-sso': 3.921.0 + '@aws-sdk/credential-provider-web-identity': 3.921.0 + '@aws-sdk/types': 3.921.0 + '@smithy/credential-provider-imds': 4.2.4 + '@smithy/property-provider': 4.2.4 + '@smithy/shared-ini-file-loader': 4.3.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-process@3.916.0': + '@aws-sdk/credential-provider-process@3.921.0': dependencies: - '@aws-sdk/core': 3.916.0 - '@aws-sdk/types': 3.914.0 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/core': 3.921.0 + '@aws-sdk/types': 3.921.0 + '@smithy/property-provider': 4.2.4 + '@smithy/shared-ini-file-loader': 4.3.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-sso@3.916.0': + '@aws-sdk/credential-provider-sso@3.921.0': dependencies: - '@aws-sdk/client-sso': 3.916.0 - '@aws-sdk/core': 3.916.0 - '@aws-sdk/token-providers': 3.916.0 - '@aws-sdk/types': 3.914.0 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/client-sso': 3.921.0 + '@aws-sdk/core': 3.921.0 + '@aws-sdk/token-providers': 3.921.0 + '@aws-sdk/types': 3.921.0 + '@smithy/property-provider': 4.2.4 + '@smithy/shared-ini-file-loader': 4.3.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-web-identity@3.916.0': + '@aws-sdk/credential-provider-web-identity@3.921.0': dependencies: - '@aws-sdk/core': 3.916.0 - '@aws-sdk/nested-clients': 3.916.0 - '@aws-sdk/types': 3.914.0 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/core': 3.921.0 + '@aws-sdk/nested-clients': 3.921.0 + '@aws-sdk/types': 3.921.0 + '@smithy/property-provider': 4.2.4 + '@smithy/shared-ini-file-loader': 4.3.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/middleware-bucket-endpoint@3.914.0': + '@aws-sdk/middleware-bucket-endpoint@3.921.0': dependencies: - '@aws-sdk/types': 3.914.0 + '@aws-sdk/types': 3.921.0 '@aws-sdk/util-arn-parser': 3.893.0 - '@smithy/node-config-provider': 4.3.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/node-config-provider': 4.3.4 + '@smithy/protocol-http': 5.3.4 + '@smithy/types': 4.8.1 '@smithy/util-config-provider': 4.2.0 tslib: 2.8.1 - '@aws-sdk/middleware-expect-continue@3.916.0': + '@aws-sdk/middleware-expect-continue@3.921.0': dependencies: - '@aws-sdk/types': 3.914.0 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/types': 3.921.0 + '@smithy/protocol-http': 5.3.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@aws-sdk/middleware-flexible-checksums@3.916.0': + '@aws-sdk/middleware-flexible-checksums@3.921.0': dependencies: '@aws-crypto/crc32': 5.2.0 '@aws-crypto/crc32c': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/core': 3.916.0 - '@aws-sdk/types': 3.914.0 + '@aws-sdk/core': 3.921.0 + '@aws-sdk/types': 3.921.0 '@smithy/is-array-buffer': 4.2.0 - '@smithy/node-config-provider': 4.3.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-stream': 4.5.4 + '@smithy/node-config-provider': 4.3.4 + '@smithy/protocol-http': 5.3.4 + '@smithy/types': 4.8.1 + '@smithy/util-middleware': 4.2.4 + '@smithy/util-stream': 4.5.5 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@aws-sdk/middleware-host-header@3.914.0': + '@aws-sdk/middleware-host-header@3.921.0': dependencies: - '@aws-sdk/types': 3.914.0 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/types': 3.921.0 + '@smithy/protocol-http': 5.3.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@aws-sdk/middleware-location-constraint@3.914.0': + '@aws-sdk/middleware-location-constraint@3.921.0': dependencies: - '@aws-sdk/types': 3.914.0 - '@smithy/types': 4.8.0 + '@aws-sdk/types': 3.921.0 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@aws-sdk/middleware-logger@3.914.0': + '@aws-sdk/middleware-logger@3.921.0': dependencies: - '@aws-sdk/types': 3.914.0 - '@smithy/types': 4.8.0 + '@aws-sdk/types': 3.921.0 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@aws-sdk/middleware-recursion-detection@3.914.0': + '@aws-sdk/middleware-recursion-detection@3.921.0': dependencies: - '@aws-sdk/types': 3.914.0 - '@aws/lambda-invoke-store': 0.0.1 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/types': 3.921.0 + '@aws/lambda-invoke-store': 0.1.1 + '@smithy/protocol-http': 5.3.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@aws-sdk/middleware-sdk-s3@3.916.0': + '@aws-sdk/middleware-sdk-s3@3.921.0': dependencies: - '@aws-sdk/core': 3.916.0 - '@aws-sdk/types': 3.914.0 + '@aws-sdk/core': 3.921.0 + '@aws-sdk/types': 3.921.0 '@aws-sdk/util-arn-parser': 3.893.0 - '@smithy/core': 3.17.1 - '@smithy/node-config-provider': 4.3.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/signature-v4': 5.3.3 - '@smithy/smithy-client': 4.9.1 - '@smithy/types': 4.8.0 + '@smithy/core': 3.17.2 + '@smithy/node-config-provider': 4.3.4 + '@smithy/protocol-http': 5.3.4 + '@smithy/signature-v4': 5.3.4 + '@smithy/smithy-client': 4.9.2 + '@smithy/types': 4.8.1 '@smithy/util-config-provider': 4.2.0 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-stream': 4.5.4 + '@smithy/util-middleware': 4.2.4 + '@smithy/util-stream': 4.5.5 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@aws-sdk/middleware-ssec@3.914.0': + '@aws-sdk/middleware-ssec@3.921.0': dependencies: - '@aws-sdk/types': 3.914.0 - '@smithy/types': 4.8.0 + '@aws-sdk/types': 3.921.0 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@aws-sdk/middleware-user-agent@3.916.0': + '@aws-sdk/middleware-user-agent@3.921.0': dependencies: - '@aws-sdk/core': 3.916.0 - '@aws-sdk/types': 3.914.0 - '@aws-sdk/util-endpoints': 3.916.0 - '@smithy/core': 3.17.1 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/core': 3.921.0 + '@aws-sdk/types': 3.921.0 + '@aws-sdk/util-endpoints': 3.921.0 + '@smithy/core': 3.17.2 + '@smithy/protocol-http': 5.3.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@aws-sdk/nested-clients@3.916.0': + '@aws-sdk/nested-clients@3.921.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.916.0 - '@aws-sdk/middleware-host-header': 3.914.0 - '@aws-sdk/middleware-logger': 3.914.0 - '@aws-sdk/middleware-recursion-detection': 3.914.0 - '@aws-sdk/middleware-user-agent': 3.916.0 - '@aws-sdk/region-config-resolver': 3.914.0 - '@aws-sdk/types': 3.914.0 - '@aws-sdk/util-endpoints': 3.916.0 - '@aws-sdk/util-user-agent-browser': 3.914.0 - '@aws-sdk/util-user-agent-node': 3.916.0 - '@smithy/config-resolver': 4.4.0 - '@smithy/core': 3.17.1 - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/hash-node': 4.2.3 - '@smithy/invalid-dependency': 4.2.3 - '@smithy/middleware-content-length': 4.2.3 - '@smithy/middleware-endpoint': 4.3.5 - '@smithy/middleware-retry': 4.4.5 - '@smithy/middleware-serde': 4.2.3 - '@smithy/middleware-stack': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/node-http-handler': 4.4.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.1 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 + '@aws-sdk/core': 3.921.0 + '@aws-sdk/middleware-host-header': 3.921.0 + '@aws-sdk/middleware-logger': 3.921.0 + '@aws-sdk/middleware-recursion-detection': 3.921.0 + '@aws-sdk/middleware-user-agent': 3.921.0 + '@aws-sdk/region-config-resolver': 3.921.0 + '@aws-sdk/types': 3.921.0 + '@aws-sdk/util-endpoints': 3.921.0 + '@aws-sdk/util-user-agent-browser': 3.921.0 + '@aws-sdk/util-user-agent-node': 3.921.0 + '@smithy/config-resolver': 4.4.1 + '@smithy/core': 3.17.2 + '@smithy/fetch-http-handler': 5.3.5 + '@smithy/hash-node': 4.2.4 + '@smithy/invalid-dependency': 4.2.4 + '@smithy/middleware-content-length': 4.2.4 + '@smithy/middleware-endpoint': 4.3.6 + '@smithy/middleware-retry': 4.4.6 + '@smithy/middleware-serde': 4.2.4 + '@smithy/middleware-stack': 4.2.4 + '@smithy/node-config-provider': 4.3.4 + '@smithy/node-http-handler': 4.4.4 + '@smithy/protocol-http': 5.3.4 + '@smithy/smithy-client': 4.9.2 + '@smithy/types': 4.8.1 + '@smithy/url-parser': 4.2.4 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.4 - '@smithy/util-defaults-mode-node': 4.2.6 - '@smithy/util-endpoints': 3.2.3 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-retry': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.5 + '@smithy/util-defaults-mode-node': 4.2.7 + '@smithy/util-endpoints': 3.2.4 + '@smithy/util-middleware': 4.2.4 + '@smithy/util-retry': 4.2.4 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 transitivePeerDependencies: @@ -12038,95 +11986,96 @@ snapshots: '@smithy/node-http-handler': 1.1.0 tslib: 2.8.1 - '@aws-sdk/region-config-resolver@3.914.0': + '@aws-sdk/region-config-resolver@3.921.0': dependencies: - '@aws-sdk/types': 3.914.0 - '@smithy/config-resolver': 4.4.0 - '@smithy/types': 4.8.0 + '@aws-sdk/types': 3.921.0 + '@smithy/config-resolver': 4.4.1 + '@smithy/node-config-provider': 4.3.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@aws-sdk/s3-request-presigner@3.916.0': + '@aws-sdk/s3-request-presigner@3.921.0': dependencies: - '@aws-sdk/signature-v4-multi-region': 3.916.0 - '@aws-sdk/types': 3.914.0 - '@aws-sdk/util-format-url': 3.914.0 - '@smithy/middleware-endpoint': 4.3.5 - '@smithy/protocol-http': 5.3.3 - '@smithy/smithy-client': 4.9.1 - '@smithy/types': 4.8.0 + '@aws-sdk/signature-v4-multi-region': 3.921.0 + '@aws-sdk/types': 3.921.0 + '@aws-sdk/util-format-url': 3.921.0 + '@smithy/middleware-endpoint': 4.3.6 + '@smithy/protocol-http': 5.3.4 + '@smithy/smithy-client': 4.9.2 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@aws-sdk/signature-v4-multi-region@3.916.0': + '@aws-sdk/signature-v4-multi-region@3.921.0': dependencies: - '@aws-sdk/middleware-sdk-s3': 3.916.0 - '@aws-sdk/types': 3.914.0 - '@smithy/protocol-http': 5.3.3 - '@smithy/signature-v4': 5.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/middleware-sdk-s3': 3.921.0 + '@aws-sdk/types': 3.921.0 + '@smithy/protocol-http': 5.3.4 + '@smithy/signature-v4': 5.3.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@aws-sdk/token-providers@3.916.0': + '@aws-sdk/token-providers@3.921.0': dependencies: - '@aws-sdk/core': 3.916.0 - '@aws-sdk/nested-clients': 3.916.0 - '@aws-sdk/types': 3.914.0 - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/core': 3.921.0 + '@aws-sdk/nested-clients': 3.921.0 + '@aws-sdk/types': 3.921.0 + '@smithy/property-provider': 4.2.4 + '@smithy/shared-ini-file-loader': 4.3.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/types@3.914.0': + '@aws-sdk/types@3.921.0': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.8.1 tslib: 2.8.1 '@aws-sdk/util-arn-parser@3.893.0': dependencies: tslib: 2.8.1 - '@aws-sdk/util-endpoints@3.916.0': + '@aws-sdk/util-endpoints@3.921.0': dependencies: - '@aws-sdk/types': 3.914.0 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 - '@smithy/util-endpoints': 3.2.3 + '@aws-sdk/types': 3.921.0 + '@smithy/types': 4.8.1 + '@smithy/url-parser': 4.2.4 + '@smithy/util-endpoints': 3.2.4 tslib: 2.8.1 - '@aws-sdk/util-format-url@3.914.0': + '@aws-sdk/util-format-url@3.921.0': dependencies: - '@aws-sdk/types': 3.914.0 - '@smithy/querystring-builder': 4.2.3 - '@smithy/types': 4.8.0 + '@aws-sdk/types': 3.921.0 + '@smithy/querystring-builder': 4.2.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 '@aws-sdk/util-locate-window@3.893.0': dependencies: tslib: 2.8.1 - '@aws-sdk/util-user-agent-browser@3.914.0': + '@aws-sdk/util-user-agent-browser@3.921.0': dependencies: - '@aws-sdk/types': 3.914.0 - '@smithy/types': 4.8.0 + '@aws-sdk/types': 3.921.0 + '@smithy/types': 4.8.1 bowser: 2.12.1 tslib: 2.8.1 - '@aws-sdk/util-user-agent-node@3.916.0': + '@aws-sdk/util-user-agent-node@3.921.0': dependencies: - '@aws-sdk/middleware-user-agent': 3.916.0 - '@aws-sdk/types': 3.914.0 - '@smithy/node-config-provider': 4.3.3 - '@smithy/types': 4.8.0 + '@aws-sdk/middleware-user-agent': 3.921.0 + '@aws-sdk/types': 3.921.0 + '@smithy/node-config-provider': 4.3.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@aws-sdk/xml-builder@3.914.0': + '@aws-sdk/xml-builder@3.921.0': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.8.1 fast-xml-parser: 5.2.5 tslib: 2.8.1 - '@aws/lambda-invoke-store@0.0.1': {} + '@aws/lambda-invoke-store@0.1.1': {} '@babel/code-frame@7.27.1': dependencies: @@ -12941,7 +12890,7 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} - '@better-auth/core@1.3.29(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.18)(better-call@1.0.19)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1)': + '@better-auth/core@1.3.34(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.18)(better-call@1.0.19)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1)': dependencies: '@better-auth/utils': 0.3.0 '@better-fetch/fetch': 1.1.18 @@ -12951,9 +12900,9 @@ snapshots: nanostores: 1.0.1 zod: 4.1.12 - '@better-auth/telemetry@1.3.29(better-call@1.0.19)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1)': + '@better-auth/telemetry@1.3.34(better-call@1.0.19)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1)': dependencies: - '@better-auth/core': 1.3.29(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.18)(better-call@1.0.19)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1) + '@better-auth/core': 1.3.34(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.18)(better-call@1.0.19)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1) '@better-auth/utils': 0.3.0 '@better-fetch/fetch': 1.1.18 transitivePeerDependencies: @@ -13049,13 +12998,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@conventional-changelog/git-client@1.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.0)': + '@conventional-changelog/git-client@1.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.1)': dependencies: '@types/semver': 7.7.1 semver: 7.7.3 optionalDependencies: conventional-commits-filter: 5.0.0 - conventional-commits-parser: 6.2.0 + conventional-commits-parser: 6.2.1 '@dnd-kit/accessibility@3.1.1(react@19.2.0)': dependencies: @@ -13681,9 +13630,9 @@ snapshots: '@hexagon/base64@1.1.28': {} - '@hono/node-server@1.19.5(hono@4.10.2)': + '@hono/node-server@1.19.6(hono@4.10.4)': dependencies: - hono: 4.10.2 + hono: 4.10.4 '@humanfs/core@0.19.1': {} @@ -13971,7 +13920,7 @@ snapshots: emoji-mart: 5.6.0 fast-deep-equal: 3.1.3 framer-motion: 12.23.24(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - immer: 10.1.3 + immer: 10.2.0 katex: 0.16.22 leva: 0.10.0(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) lodash-es: 4.17.21 @@ -14002,7 +13951,7 @@ snapshots: remark-gfm: 4.0.1 remark-github: 12.0.0 remark-math: 6.0.0 - shiki: 3.13.0 + shiki: 3.14.0 swr: 2.3.6(react@19.2.0) ts-md5: 1.3.1 unified: 11.0.5 @@ -14047,11 +13996,11 @@ snapshots: '@mapbox/whoots-js@3.1.0': {} - '@maplibre/maplibre-gl-geocoder@1.9.1(maplibre-gl@5.9.0)': + '@maplibre/maplibre-gl-geocoder@1.9.1(maplibre-gl@5.10.0)': dependencies: events: 3.3.0 lodash.debounce: 4.0.8 - maplibre-gl: 5.9.0 + maplibre-gl: 5.10.0 subtag: 0.5.0 suggestions-list: 0.0.2 xtend: 4.0.2 @@ -14065,7 +14014,7 @@ snapshots: rw: 1.3.3 sort-object: 3.0.3 - '@maplibre/maplibre-gl-style-spec@24.3.0': + '@maplibre/maplibre-gl-style-spec@24.3.1': dependencies: '@mapbox/jsonlint-lines-primitives': 2.0.2 '@mapbox/unitbezier': 0.0.1 @@ -14165,24 +14114,24 @@ snapshots: dependencies: langium: 3.3.1 - '@microsoft/api-extractor-model@7.30.7(@types/node@24.9.1)': + '@microsoft/api-extractor-model@7.30.7(@types/node@24.9.2)': dependencies: '@microsoft/tsdoc': 0.15.1 '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.14.0(@types/node@24.9.1) + '@rushstack/node-core-library': 5.14.0(@types/node@24.9.2) transitivePeerDependencies: - '@types/node' optional: true - '@microsoft/api-extractor@7.52.13(@types/node@24.9.1)': + '@microsoft/api-extractor@7.52.13(@types/node@24.9.2)': dependencies: - '@microsoft/api-extractor-model': 7.30.7(@types/node@24.9.1) + '@microsoft/api-extractor-model': 7.30.7(@types/node@24.9.2) '@microsoft/tsdoc': 0.15.1 '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.14.0(@types/node@24.9.1) + '@rushstack/node-core-library': 5.14.0(@types/node@24.9.2) '@rushstack/rig-package': 0.5.3 - '@rushstack/terminal': 0.16.0(@types/node@24.9.1) - '@rushstack/ts-command-line': 5.0.3(@types/node@24.9.1) + '@rushstack/terminal': 0.16.0(@types/node@24.9.2) + '@rushstack/ts-command-line': 5.0.3(@types/node@24.9.2) lodash: 4.17.21 minimatch: 10.0.3 resolve: 1.22.11 @@ -14223,30 +14172,30 @@ snapshots: '@types/pg': 8.11.6 optional: true - '@next/env@16.0.0': {} + '@next/env@16.0.1': {} - '@next/swc-darwin-arm64@16.0.0': + '@next/swc-darwin-arm64@16.0.1': optional: true - '@next/swc-darwin-x64@16.0.0': + '@next/swc-darwin-x64@16.0.1': optional: true - '@next/swc-linux-arm64-gnu@16.0.0': + '@next/swc-linux-arm64-gnu@16.0.1': optional: true - '@next/swc-linux-arm64-musl@16.0.0': + '@next/swc-linux-arm64-musl@16.0.1': optional: true - '@next/swc-linux-x64-gnu@16.0.0': + '@next/swc-linux-x64-gnu@16.0.1': optional: true - '@next/swc-linux-x64-musl@16.0.0': + '@next/swc-linux-x64-musl@16.0.1': optional: true - '@next/swc-win32-arm64-msvc@16.0.0': + '@next/swc-win32-arm64-msvc@16.0.1': optional: true - '@next/swc-win32-x64-msvc@16.0.0': + '@next/swc-win32-x64-msvc@16.0.1': optional: true '@noble/ciphers@2.0.1': {} @@ -15463,53 +15412,53 @@ snapshots: '@reteps/dockerfmt@0.3.6': {} - '@rolldown/binding-android-arm64@1.0.0-beta.44': + '@rolldown/binding-android-arm64@1.0.0-beta.45': optional: true - '@rolldown/binding-darwin-arm64@1.0.0-beta.44': + '@rolldown/binding-darwin-arm64@1.0.0-beta.45': optional: true - '@rolldown/binding-darwin-x64@1.0.0-beta.44': + '@rolldown/binding-darwin-x64@1.0.0-beta.45': optional: true - '@rolldown/binding-freebsd-x64@1.0.0-beta.44': + '@rolldown/binding-freebsd-x64@1.0.0-beta.45': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.44': + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.45': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.44': + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.45': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.44': + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.45': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.44': + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.45': optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-beta.44': + '@rolldown/binding-linux-x64-musl@1.0.0-beta.45': optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-beta.44': + '@rolldown/binding-openharmony-arm64@1.0.0-beta.45': optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-beta.44': + '@rolldown/binding-wasm32-wasi@1.0.0-beta.45': dependencies: '@napi-rs/wasm-runtime': 1.0.7 optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.44': + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.45': optional: true - '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.44': + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.45': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.44': + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.45': optional: true '@rolldown/pluginutils@1.0.0-beta.43': {} - '@rolldown/pluginutils@1.0.0-beta.44': {} + '@rolldown/pluginutils@1.0.0-beta.45': {} '@rollup/plugin-babel@5.3.1(@babel/core@7.28.5)(@types/babel__core@7.20.5)(rollup@2.79.2)': dependencies: @@ -15640,7 +15589,7 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.52.5': optional: true - '@rushstack/node-core-library@5.14.0(@types/node@24.9.1)': + '@rushstack/node-core-library@5.14.0(@types/node@24.9.2)': dependencies: ajv: 8.13.0 ajv-draft-04: 1.0.0(ajv@8.13.0) @@ -15651,7 +15600,7 @@ snapshots: resolve: 1.22.11 semver: 7.5.4 optionalDependencies: - '@types/node': 24.9.1 + '@types/node': 24.9.2 optional: true '@rushstack/rig-package@0.5.3': @@ -15660,17 +15609,17 @@ snapshots: strip-json-comments: 3.1.1 optional: true - '@rushstack/terminal@0.16.0(@types/node@24.9.1)': + '@rushstack/terminal@0.16.0(@types/node@24.9.2)': dependencies: - '@rushstack/node-core-library': 5.14.0(@types/node@24.9.1) + '@rushstack/node-core-library': 5.14.0(@types/node@24.9.2) supports-color: 8.1.1 optionalDependencies: - '@types/node': 24.9.1 + '@types/node': 24.9.2 optional: true - '@rushstack/ts-command-line@5.0.3(@types/node@24.9.1)': + '@rushstack/ts-command-line@5.0.3(@types/node@24.9.2)': dependencies: - '@rushstack/terminal': 0.16.0(@types/node@24.9.1) + '@rushstack/terminal': 0.16.0(@types/node@24.9.2) '@types/argparse': 1.0.38 argparse: 1.0.10 string-argv: 0.3.2 @@ -15680,9 +15629,9 @@ snapshots: '@sec-ant/readable-stream@0.4.1': {} - '@shikijs/core@3.13.0': + '@shikijs/core@3.14.0': dependencies: - '@shikijs/types': 3.13.0 + '@shikijs/types': 3.14.0 '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 hast-util-to-html: 9.0.5 @@ -15694,40 +15643,40 @@ snapshots: '@types/hast': 3.0.4 hast-util-to-html: 9.0.5 - '@shikijs/engine-javascript@3.13.0': + '@shikijs/engine-javascript@3.14.0': dependencies: - '@shikijs/types': 3.13.0 + '@shikijs/types': 3.14.0 '@shikijs/vscode-textmate': 10.0.2 oniguruma-to-es: 4.3.3 - '@shikijs/engine-oniguruma@3.13.0': + '@shikijs/engine-oniguruma@3.14.0': dependencies: - '@shikijs/types': 3.13.0 + '@shikijs/types': 3.14.0 '@shikijs/vscode-textmate': 10.0.2 - '@shikijs/langs@3.13.0': + '@shikijs/langs@3.14.0': dependencies: - '@shikijs/types': 3.13.0 + '@shikijs/types': 3.14.0 - '@shikijs/rehype@3.13.0': + '@shikijs/rehype@3.14.0': dependencies: - '@shikijs/types': 3.13.0 + '@shikijs/types': 3.14.0 '@types/hast': 3.0.4 hast-util-to-string: 3.0.1 - shiki: 3.13.0 + shiki: 3.14.0 unified: 11.0.5 unist-util-visit: 5.0.0 - '@shikijs/themes@3.13.0': + '@shikijs/themes@3.14.0': dependencies: - '@shikijs/types': 3.13.0 + '@shikijs/types': 3.14.0 '@shikijs/transformers@3.7.0': dependencies: '@shikijs/core': 3.7.0 '@shikijs/types': 3.7.0 - '@shikijs/types@3.13.0': + '@shikijs/types@3.14.0': dependencies: '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 @@ -15759,9 +15708,9 @@ snapshots: '@smithy/types': 1.2.0 tslib: 2.8.1 - '@smithy/abort-controller@4.2.3': + '@smithy/abort-controller@4.2.4': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.8.1 tslib: 2.8.1 '@smithy/chunked-blob-reader-native@4.2.1': @@ -15773,97 +15722,97 @@ snapshots: dependencies: tslib: 2.8.1 - '@smithy/config-resolver@4.4.0': + '@smithy/config-resolver@4.4.1': dependencies: - '@smithy/node-config-provider': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/node-config-provider': 4.3.4 + '@smithy/types': 4.8.1 '@smithy/util-config-provider': 4.2.0 - '@smithy/util-endpoints': 3.2.3 - '@smithy/util-middleware': 4.2.3 + '@smithy/util-endpoints': 3.2.4 + '@smithy/util-middleware': 4.2.4 tslib: 2.8.1 - '@smithy/core@3.17.1': + '@smithy/core@3.17.2': dependencies: - '@smithy/middleware-serde': 4.2.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/middleware-serde': 4.2.4 + '@smithy/protocol-http': 5.3.4 + '@smithy/types': 4.8.1 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-stream': 4.5.4 + '@smithy/util-middleware': 4.2.4 + '@smithy/util-stream': 4.5.5 '@smithy/util-utf8': 4.2.0 '@smithy/uuid': 1.1.0 tslib: 2.8.1 - '@smithy/credential-provider-imds@4.2.3': + '@smithy/credential-provider-imds@4.2.4': dependencies: - '@smithy/node-config-provider': 4.3.3 - '@smithy/property-provider': 4.2.3 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 + '@smithy/node-config-provider': 4.3.4 + '@smithy/property-provider': 4.2.4 + '@smithy/types': 4.8.1 + '@smithy/url-parser': 4.2.4 tslib: 2.8.1 - '@smithy/eventstream-codec@4.2.3': + '@smithy/eventstream-codec@4.2.4': dependencies: '@aws-crypto/crc32': 5.2.0 - '@smithy/types': 4.8.0 + '@smithy/types': 4.8.1 '@smithy/util-hex-encoding': 4.2.0 tslib: 2.8.1 - '@smithy/eventstream-serde-browser@4.2.3': + '@smithy/eventstream-serde-browser@4.2.4': dependencies: - '@smithy/eventstream-serde-universal': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/eventstream-serde-universal': 4.2.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@smithy/eventstream-serde-config-resolver@4.3.3': + '@smithy/eventstream-serde-config-resolver@4.3.4': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@smithy/eventstream-serde-node@4.2.3': + '@smithy/eventstream-serde-node@4.2.4': dependencies: - '@smithy/eventstream-serde-universal': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/eventstream-serde-universal': 4.2.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@smithy/eventstream-serde-universal@4.2.3': + '@smithy/eventstream-serde-universal@4.2.4': dependencies: - '@smithy/eventstream-codec': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/eventstream-codec': 4.2.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@smithy/fetch-http-handler@5.3.4': + '@smithy/fetch-http-handler@5.3.5': dependencies: - '@smithy/protocol-http': 5.3.3 - '@smithy/querystring-builder': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/protocol-http': 5.3.4 + '@smithy/querystring-builder': 4.2.4 + '@smithy/types': 4.8.1 '@smithy/util-base64': 4.3.0 tslib: 2.8.1 - '@smithy/hash-blob-browser@4.2.4': + '@smithy/hash-blob-browser@4.2.5': dependencies: '@smithy/chunked-blob-reader': 5.2.0 '@smithy/chunked-blob-reader-native': 4.2.1 - '@smithy/types': 4.8.0 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@smithy/hash-node@4.2.3': + '@smithy/hash-node@4.2.4': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.8.1 '@smithy/util-buffer-from': 4.2.0 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@smithy/hash-stream-node@4.2.3': + '@smithy/hash-stream-node@4.2.4': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.8.1 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@smithy/invalid-dependency@4.2.3': + '@smithy/invalid-dependency@4.2.4': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.8.1 tslib: 2.8.1 '@smithy/is-array-buffer@2.2.0': @@ -15874,57 +15823,57 @@ snapshots: dependencies: tslib: 2.8.1 - '@smithy/md5-js@4.2.3': + '@smithy/md5-js@4.2.4': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.8.1 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@smithy/middleware-content-length@4.2.3': + '@smithy/middleware-content-length@4.2.4': dependencies: - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/protocol-http': 5.3.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@smithy/middleware-endpoint@4.3.5': + '@smithy/middleware-endpoint@4.3.6': dependencies: - '@smithy/core': 3.17.1 - '@smithy/middleware-serde': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 - '@smithy/url-parser': 4.2.3 - '@smithy/util-middleware': 4.2.3 + '@smithy/core': 3.17.2 + '@smithy/middleware-serde': 4.2.4 + '@smithy/node-config-provider': 4.3.4 + '@smithy/shared-ini-file-loader': 4.3.4 + '@smithy/types': 4.8.1 + '@smithy/url-parser': 4.2.4 + '@smithy/util-middleware': 4.2.4 tslib: 2.8.1 - '@smithy/middleware-retry@4.4.5': + '@smithy/middleware-retry@4.4.6': dependencies: - '@smithy/node-config-provider': 4.3.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/service-error-classification': 4.2.3 - '@smithy/smithy-client': 4.9.1 - '@smithy/types': 4.8.0 - '@smithy/util-middleware': 4.2.3 - '@smithy/util-retry': 4.2.3 + '@smithy/node-config-provider': 4.3.4 + '@smithy/protocol-http': 5.3.4 + '@smithy/service-error-classification': 4.2.4 + '@smithy/smithy-client': 4.9.2 + '@smithy/types': 4.8.1 + '@smithy/util-middleware': 4.2.4 + '@smithy/util-retry': 4.2.4 '@smithy/uuid': 1.1.0 tslib: 2.8.1 - '@smithy/middleware-serde@4.2.3': + '@smithy/middleware-serde@4.2.4': dependencies: - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/protocol-http': 5.3.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@smithy/middleware-stack@4.2.3': + '@smithy/middleware-stack@4.2.4': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@smithy/node-config-provider@4.3.3': + '@smithy/node-config-provider@4.3.4': dependencies: - '@smithy/property-provider': 4.2.3 - '@smithy/shared-ini-file-loader': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/property-provider': 4.2.4 + '@smithy/shared-ini-file-loader': 4.3.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 '@smithy/node-http-handler@1.1.0': @@ -15935,17 +15884,17 @@ snapshots: '@smithy/types': 1.2.0 tslib: 2.8.1 - '@smithy/node-http-handler@4.4.3': + '@smithy/node-http-handler@4.4.4': dependencies: - '@smithy/abort-controller': 4.2.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/querystring-builder': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/abort-controller': 4.2.4 + '@smithy/protocol-http': 5.3.4 + '@smithy/querystring-builder': 4.2.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@smithy/property-provider@4.2.3': + '@smithy/property-provider@4.2.4': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.8.1 tslib: 2.8.1 '@smithy/protocol-http@1.2.0': @@ -15953,9 +15902,9 @@ snapshots: '@smithy/types': 1.2.0 tslib: 2.8.1 - '@smithy/protocol-http@5.3.3': + '@smithy/protocol-http@5.3.4': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.8.1 tslib: 2.8.1 '@smithy/querystring-builder@1.1.0': @@ -15964,59 +15913,59 @@ snapshots: '@smithy/util-uri-escape': 1.1.0 tslib: 2.8.1 - '@smithy/querystring-builder@4.2.3': + '@smithy/querystring-builder@4.2.4': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.8.1 '@smithy/util-uri-escape': 4.2.0 tslib: 2.8.1 - '@smithy/querystring-parser@4.2.3': + '@smithy/querystring-parser@4.2.4': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@smithy/service-error-classification@4.2.3': + '@smithy/service-error-classification@4.2.4': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.8.1 - '@smithy/shared-ini-file-loader@4.3.3': + '@smithy/shared-ini-file-loader@4.3.4': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@smithy/signature-v4@5.3.3': + '@smithy/signature-v4@5.3.4': dependencies: '@smithy/is-array-buffer': 4.2.0 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 + '@smithy/protocol-http': 5.3.4 + '@smithy/types': 4.8.1 '@smithy/util-hex-encoding': 4.2.0 - '@smithy/util-middleware': 4.2.3 + '@smithy/util-middleware': 4.2.4 '@smithy/util-uri-escape': 4.2.0 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@smithy/smithy-client@4.9.1': + '@smithy/smithy-client@4.9.2': dependencies: - '@smithy/core': 3.17.1 - '@smithy/middleware-endpoint': 4.3.5 - '@smithy/middleware-stack': 4.2.3 - '@smithy/protocol-http': 5.3.3 - '@smithy/types': 4.8.0 - '@smithy/util-stream': 4.5.4 + '@smithy/core': 3.17.2 + '@smithy/middleware-endpoint': 4.3.6 + '@smithy/middleware-stack': 4.2.4 + '@smithy/protocol-http': 5.3.4 + '@smithy/types': 4.8.1 + '@smithy/util-stream': 4.5.5 tslib: 2.8.1 '@smithy/types@1.2.0': dependencies: tslib: 2.8.1 - '@smithy/types@4.8.0': + '@smithy/types@4.8.1': dependencies: tslib: 2.8.1 - '@smithy/url-parser@4.2.3': + '@smithy/url-parser@4.2.4': dependencies: - '@smithy/querystring-parser': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/querystring-parser': 4.2.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 '@smithy/util-base64@4.3.0': @@ -16047,49 +15996,49 @@ snapshots: dependencies: tslib: 2.8.1 - '@smithy/util-defaults-mode-browser@4.3.4': + '@smithy/util-defaults-mode-browser@4.3.5': dependencies: - '@smithy/property-provider': 4.2.3 - '@smithy/smithy-client': 4.9.1 - '@smithy/types': 4.8.0 + '@smithy/property-provider': 4.2.4 + '@smithy/smithy-client': 4.9.2 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@smithy/util-defaults-mode-node@4.2.6': + '@smithy/util-defaults-mode-node@4.2.7': dependencies: - '@smithy/config-resolver': 4.4.0 - '@smithy/credential-provider-imds': 4.2.3 - '@smithy/node-config-provider': 4.3.3 - '@smithy/property-provider': 4.2.3 - '@smithy/smithy-client': 4.9.1 - '@smithy/types': 4.8.0 + '@smithy/config-resolver': 4.4.1 + '@smithy/credential-provider-imds': 4.2.4 + '@smithy/node-config-provider': 4.3.4 + '@smithy/property-provider': 4.2.4 + '@smithy/smithy-client': 4.9.2 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@smithy/util-endpoints@3.2.3': + '@smithy/util-endpoints@3.2.4': dependencies: - '@smithy/node-config-provider': 4.3.3 - '@smithy/types': 4.8.0 + '@smithy/node-config-provider': 4.3.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 '@smithy/util-hex-encoding@4.2.0': dependencies: tslib: 2.8.1 - '@smithy/util-middleware@4.2.3': + '@smithy/util-middleware@4.2.4': dependencies: - '@smithy/types': 4.8.0 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@smithy/util-retry@4.2.3': + '@smithy/util-retry@4.2.4': dependencies: - '@smithy/service-error-classification': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/service-error-classification': 4.2.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 - '@smithy/util-stream@4.5.4': + '@smithy/util-stream@4.5.5': dependencies: - '@smithy/fetch-http-handler': 5.3.4 - '@smithy/node-http-handler': 4.4.3 - '@smithy/types': 4.8.0 + '@smithy/fetch-http-handler': 5.3.5 + '@smithy/node-http-handler': 4.4.4 + '@smithy/types': 4.8.1 '@smithy/util-base64': 4.3.0 '@smithy/util-buffer-from': 4.2.0 '@smithy/util-hex-encoding': 4.2.0 @@ -16114,10 +16063,10 @@ snapshots: '@smithy/util-buffer-from': 4.2.0 tslib: 2.8.1 - '@smithy/util-waiter@4.2.3': + '@smithy/util-waiter@4.2.4': dependencies: - '@smithy/abort-controller': 4.2.3 - '@smithy/types': 4.8.0 + '@smithy/abort-controller': 4.2.4 + '@smithy/types': 4.8.1 tslib: 2.8.1 '@smithy/uuid@1.1.0': @@ -16303,12 +16252,12 @@ snapshots: postcss-selector-parser: 6.0.10 tailwindcss: 4.1.16 - '@tailwindcss/vite@4.1.16(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@tailwindcss/vite@4.1.16(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@tailwindcss/node': 4.1.16 '@tailwindcss/oxide': 4.1.16 tailwindcss: 4.1.16 - vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) '@tanstack/query-core@5.90.5': {} @@ -16540,13 +16489,18 @@ snapshots: '@types/ms@2.1.0': {} - '@types/node@20.19.23': + '@types/node@20.19.24': dependencies: undici-types: 6.21.0 '@types/node@24.9.1': dependencies: undici-types: 7.16.0 + optional: true + + '@types/node@24.9.2': + dependencies: + undici-types: 7.16.0 '@types/node@8.10.66': {} @@ -16566,9 +16520,9 @@ snapshots: pg-types: 4.1.0 optional: true - '@types/pg@8.15.5': + '@types/pg@8.15.6': dependencies: - '@types/node': 24.9.1 + '@types/node': 24.9.2 pg-protocol: 1.10.3 pg-types: 2.2.0 @@ -16909,7 +16863,7 @@ snapshots: '@use-gesture/core': 10.3.1 react: 19.2.0 - '@uswriting/exiftool@1.0.3': {} + '@uswriting/exiftool@1.0.5': {} '@vercel/postgres@0.10.0': dependencies: @@ -16931,15 +16885,15 @@ snapshots: optionalDependencies: mapbox-gl: 3.13.0 - '@vis.gl/react-maplibre@8.1.0(maplibre-gl@5.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@vis.gl/react-maplibre@8.1.0(maplibre-gl@5.10.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@maplibre/maplibre-gl-style-spec': 19.3.3 react: 19.2.0 react-dom: 19.2.0(react@19.2.0) optionalDependencies: - maplibre-gl: 5.9.0 + maplibre-gl: 5.10.0 - '@vitejs/plugin-react@5.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@vitejs/plugin-react@5.1.0(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@babel/core': 7.28.5 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) @@ -16947,14 +16901,14 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.43 '@types/babel__core': 7.20.5 react-refresh: 0.18.0 - vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - supports-color - '@vitest/coverage-v8@4.0.3(vitest@4.0.3(@types/debug@4.1.12)(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@vitest/coverage-v8@4.0.6(vitest@4.0.6(@types/debug@4.1.12)(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.0.3 + '@vitest/utils': 4.0.6 ast-v8-to-istanbul: 0.3.8 debug: 4.4.3(supports-color@5.5.0) istanbul-lib-coverage: 3.2.2 @@ -16964,47 +16918,47 @@ snapshots: magicast: 0.3.5 std-env: 3.10.0 tinyrainbow: 3.0.3 - vitest: 4.0.3(@types/debug@4.1.12)(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vitest: 4.0.6(@types/debug@4.1.12)(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - supports-color - '@vitest/expect@4.0.3': + '@vitest/expect@4.0.6': dependencies: '@standard-schema/spec': 1.0.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.0.3 - '@vitest/utils': 4.0.3 + '@vitest/spy': 4.0.6 + '@vitest/utils': 4.0.6 chai: 6.2.0 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.3(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@vitest/mocker@4.0.6(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: - '@vitest/spy': 4.0.3 + '@vitest/spy': 4.0.6 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) - '@vitest/pretty-format@4.0.3': + '@vitest/pretty-format@4.0.6': dependencies: tinyrainbow: 3.0.3 - '@vitest/runner@4.0.3': + '@vitest/runner@4.0.6': dependencies: - '@vitest/utils': 4.0.3 + '@vitest/utils': 4.0.6 pathe: 2.0.3 - '@vitest/snapshot@4.0.3': + '@vitest/snapshot@4.0.6': dependencies: - '@vitest/pretty-format': 4.0.3 + '@vitest/pretty-format': 4.0.6 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.0.3': {} + '@vitest/spy@4.0.6': {} - '@vitest/utils@4.0.3': + '@vitest/utils@4.0.6': dependencies: - '@vitest/pretty-format': 4.0.3 + '@vitest/pretty-format': 4.0.6 tinyrainbow: 3.0.3 '@volar/language-core@2.4.23': @@ -17146,14 +17100,14 @@ snapshots: '@rc-component/trigger': 2.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) classnames: 2.5.1 copy-to-clipboard: 3.3.3 - dayjs: 1.11.18 + dayjs: 1.11.19 rc-cascader: 3.34.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) rc-checkbox: 3.5.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) rc-collapse: 3.9.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) rc-dialog: 9.6.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) rc-drawer: 7.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) rc-dropdown: 4.2.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - rc-field-form: 2.7.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + rc-field-form: 2.7.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) rc-image: 7.12.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) rc-input: 1.8.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) rc-input-number: 9.5.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -17162,7 +17116,7 @@ snapshots: rc-motion: 2.9.5(react-dom@19.2.0(react@19.2.0))(react@19.2.0) rc-notification: 5.6.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0) rc-pagination: 5.1.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - rc-picker: 4.11.3(dayjs@1.11.18)(luxon@3.7.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + rc-picker: 4.11.3(dayjs@1.11.19)(luxon@3.7.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) rc-progress: 4.0.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) rc-rate: 2.13.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) rc-resize-observer: 1.4.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -17228,7 +17182,7 @@ snapshots: asn1js@3.0.6: dependencies: pvtsutils: 1.3.6 - pvutils: 1.1.3 + pvutils: 1.1.5 tslib: 2.8.1 assertion-error@2.0.1: {} @@ -17361,10 +17315,10 @@ snapshots: batch-cluster@15.0.1: {} - better-auth@1.3.29(next@16.0.0(@babel/core@7.28.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + better-auth@1.3.34(next@16.0.1(@babel/core@7.28.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: - '@better-auth/core': 1.3.29(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.18)(better-call@1.0.19)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1) - '@better-auth/telemetry': 1.3.29(better-call@1.0.19)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1) + '@better-auth/core': 1.3.34(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.18)(better-call@1.0.19)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1) + '@better-auth/telemetry': 1.3.34(better-call@1.0.19)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1) '@better-auth/utils': 0.3.0 '@better-fetch/fetch': 1.1.18 '@noble/ciphers': 2.0.1 @@ -17378,7 +17332,7 @@ snapshots: nanostores: 1.0.1 zod: 4.1.12 optionalDependencies: - next: 16.0.0(@babel/core@7.28.5)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + next: 16.0.1(@babel/core@7.28.5)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react: 19.2.0 react-dom: 19.2.0(react@19.2.0) @@ -17387,7 +17341,7 @@ snapshots: '@better-auth/utils': 0.3.0 '@better-fetch/fetch': 1.1.18 rou3: 0.5.1 - set-cookie-parser: 2.7.1 + set-cookie-parser: 2.7.2 uncrypto: 0.1.3 binary-extensions@2.3.0: {} @@ -17448,24 +17402,7 @@ snapshots: bytewise-core: 1.2.3 typewise: 1.0.3 - c12@1.11.2(magicast@0.3.5): - dependencies: - chokidar: 3.6.0 - confbox: 0.1.8 - defu: 6.1.4 - dotenv: 16.6.1 - giget: 1.2.5 - jiti: 1.21.7 - mlly: 1.8.0 - ohash: 1.1.6 - pathe: 1.1.2 - perfect-debounce: 1.0.0 - pkg-types: 1.3.1 - rc9: 2.1.2 - optionalDependencies: - magicast: 0.3.5 - - c12@3.3.0(magicast@0.3.5): + c12@3.3.1(magicast@0.3.5): dependencies: chokidar: 4.0.3 confbox: 0.2.2 @@ -17512,6 +17449,8 @@ snapshots: caniuse-lite@1.0.30001751: {} + caniuse-lite@1.0.30001752: {} + ccount@2.0.1: {} chai@6.2.0: {} @@ -17569,8 +17508,6 @@ snapshots: dependencies: readdirp: 4.1.2 - chownr@2.0.0: {} - chroma-js@3.1.2: {} ci-info@4.3.0: {} @@ -17692,7 +17629,7 @@ snapshots: consola@3.4.2: {} - conventional-changelog-angular@8.0.0: + conventional-changelog-angular@8.1.0: dependencies: compare-func: 2.0.0 @@ -17709,9 +17646,9 @@ snapshots: '@hutson/parse-repository-url': 5.0.0 add-stream: 1.0.0 conventional-changelog-writer: 8.2.0 - conventional-commits-parser: 6.2.0 - git-raw-commits: 5.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.0) - git-semver-tags: 8.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.0) + conventional-commits-parser: 6.2.1 + git-raw-commits: 5.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.1) + git-semver-tags: 8.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.1) hosted-git-info: 7.0.2 normalize-package-data: 6.0.2 read-package-up: 11.0.0 @@ -17742,7 +17679,7 @@ snapshots: conventional-changelog@6.0.0(conventional-commits-filter@5.0.0): dependencies: - conventional-changelog-angular: 8.0.0 + conventional-changelog-angular: 8.1.0 conventional-changelog-atom: 5.0.0 conventional-changelog-codemirror: 5.0.0 conventional-changelog-conventionalcommits: 8.0.0 @@ -17758,7 +17695,7 @@ snapshots: conventional-commits-filter@5.0.0: {} - conventional-commits-parser@6.2.0: + conventional-commits-parser@6.2.1: dependencies: meow: 13.2.0 @@ -18031,7 +17968,7 @@ snapshots: d3: 7.9.0 lodash-es: 4.17.21 - daisyui@5.3.9: {} + daisyui@5.3.10: {} data-view-buffer@1.0.2: dependencies: @@ -18053,7 +17990,7 @@ snapshots: dayjs@1.11.13: {} - dayjs@1.11.18: {} + dayjs@1.11.19: {} debug@3.2.7: dependencies: @@ -18171,7 +18108,7 @@ snapshots: dotenv@17.2.3: {} - drizzle-kit@0.31.5: + drizzle-kit@0.31.6: dependencies: '@drizzle-team/brocli': 0.10.2 '@esbuild-kit/esm-loader': 2.6.5 @@ -18180,9 +18117,9 @@ snapshots: transitivePeerDependencies: - supports-color - drizzle-orm@0.44.7(@types/pg@8.15.5)(@vercel/postgres@0.10.0)(kysely@0.28.8)(pg@8.16.3)(postgres@3.4.7): + drizzle-orm@0.44.7(@types/pg@8.15.6)(@vercel/postgres@0.10.0)(kysely@0.28.8)(pg@8.16.3)(postgres@3.4.7): optionalDependencies: - '@types/pg': 8.15.5 + '@types/pg': 8.15.6 '@vercel/postgres': 0.10.0 kysely: 0.28.8 pg: 8.16.3 @@ -18694,10 +18631,10 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-react-hooks@7.0.0(eslint@9.38.0(jiti@2.6.1)): + eslint-plugin-react-hooks@7.0.1(eslint@9.38.0(jiti@2.6.1)): dependencies: - '@babel/core': 7.28.4 - '@babel/parser': 7.28.4 + '@babel/core': 7.28.5 + '@babel/parser': 7.28.5 eslint: 9.38.0(jiti@2.6.1) hermes-parser: 0.25.1 zod: 4.1.12 @@ -18958,13 +18895,13 @@ snapshots: strip-final-newline: 4.0.0 yoctocolors: 2.1.1 - exiftool-vendored.exe@13.38.0: + exiftool-vendored.exe@13.40.0: optional: true - exiftool-vendored.pl@13.38.0: + exiftool-vendored.pl@13.40.0: optional: true - exiftool-vendored@31.1.0: + exiftool-vendored@31.2.0: dependencies: '@photostructure/tz-lookup': 11.2.1 '@types/luxon': 3.7.1 @@ -18972,8 +18909,8 @@ snapshots: he: 1.2.0 luxon: 3.7.2 optionalDependencies: - exiftool-vendored.exe: 13.38.0 - exiftool-vendored.pl: 13.38.0 + exiftool-vendored.exe: 13.40.0 + exiftool-vendored.pl: 13.40.0 expect-type@1.2.2: {} @@ -19126,10 +19063,6 @@ snapshots: jsonfile: 6.2.0 universalify: 2.0.1 - fs-minipass@2.1.0: - dependencies: - minipass: 3.3.6 - fs.realpath@1.0.0: {} fsevents@2.3.2: @@ -19212,16 +19145,6 @@ snapshots: get-value@2.0.6: {} - giget@1.2.5: - dependencies: - citty: 0.1.6 - consola: 3.4.2 - defu: 6.1.4 - node-fetch-native: 1.6.7 - nypm: 0.5.4 - pathe: 2.0.3 - tar: 6.2.1 - giget@2.0.0: dependencies: citty: 0.1.6 @@ -19237,17 +19160,17 @@ snapshots: git-hooks-list@4.1.1: {} - git-raw-commits@5.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.0): + git-raw-commits@5.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.1): dependencies: - '@conventional-changelog/git-client': 1.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.0) + '@conventional-changelog/git-client': 1.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.1) meow: 13.2.0 transitivePeerDependencies: - conventional-commits-filter - conventional-commits-parser - git-semver-tags@8.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.0): + git-semver-tags@8.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.1): dependencies: - '@conventional-changelog/git-client': 1.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.0) + '@conventional-changelog/git-client': 1.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.1) meow: 13.2.0 transitivePeerDependencies: - conventional-commits-filter @@ -19507,7 +19430,7 @@ snapshots: dependencies: react-is: 16.13.1 - hono@4.10.2: {} + hono@4.10.4: {} hookable@5.5.3: {} @@ -19572,7 +19495,7 @@ snapshots: ignore@7.0.5: {} - immer@10.1.3: {} + immer@10.2.0: {} import-fresh@3.3.1: dependencies: @@ -19838,8 +19761,6 @@ snapshots: filelist: 1.0.4 minimatch: 3.1.2 - jiti@1.21.7: {} - jiti@2.6.1: {} jju@1.4.0: @@ -20140,7 +20061,7 @@ snapshots: dependencies: react: 19.2.0 - lucide-react@0.547.0(react@19.2.0): + lucide-react@0.552.0(react@19.2.0): dependencies: react: 19.2.0 @@ -20205,7 +20126,7 @@ snapshots: vt-pbf: 3.1.3 optional: true - maplibre-gl@5.9.0: + maplibre-gl@5.10.0: dependencies: '@mapbox/geojson-rewind': 0.5.2 '@mapbox/jsonlint-lines-primitives': 2.0.2 @@ -20214,7 +20135,7 @@ snapshots: '@mapbox/unitbezier': 0.0.1 '@mapbox/vector-tile': 2.0.4 '@mapbox/whoots-js': 3.1.0 - '@maplibre/maplibre-gl-style-spec': 24.3.0 + '@maplibre/maplibre-gl-style-spec': 24.3.1 '@maplibre/vt-pbf': 4.0.3 '@types/geojson': 7946.0.16 '@types/geojson-vt': 3.2.5 @@ -20797,26 +20718,13 @@ snapshots: minimist@1.2.8: {} - minipass@3.3.6: - dependencies: - yallist: 4.0.0 - - minipass@5.0.0: {} - minipass@7.1.2: {} - minizlib@2.1.2: - dependencies: - minipass: 3.3.6 - yallist: 4.0.0 - mixin-deep@1.3.2: dependencies: for-in: 1.0.2 is-extendable: 1.0.1 - mkdirp@1.0.4: {} - mlly@1.8.0: dependencies: acorn: 8.15.0 @@ -20869,21 +20777,12 @@ snapshots: natural-compare@1.4.0: {} - nbump@2.1.7(conventional-commits-filter@5.0.0)(magicast@0.3.5): - dependencies: - c12: 3.3.0(magicast@0.3.5) - conventional-changelog: 6.0.0(conventional-commits-filter@5.0.0) - zx: 8.8.2 - transitivePeerDependencies: - - conventional-commits-filter - - magicast - nbump@2.1.8(conventional-commits-filter@5.0.0)(magicast@0.3.5): dependencies: - c12: 3.3.0(magicast@0.3.5) + c12: 3.3.1(magicast@0.3.5) conventional-changelog: 6.0.0(conventional-commits-filter@5.0.0) package-manager-detector: 1.5.0 - zx: 8.8.2 + zx: 8.8.5 transitivePeerDependencies: - conventional-commits-filter - magicast @@ -20895,24 +20794,24 @@ snapshots: react: 19.2.0 react-dom: 19.2.0(react@19.2.0) - next@16.0.0(@babel/core@7.28.5)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + next@16.0.1(@babel/core@7.28.5)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: - '@next/env': 16.0.0 + '@next/env': 16.0.1 '@swc/helpers': 0.5.15 - caniuse-lite: 1.0.30001751 + caniuse-lite: 1.0.30001752 postcss: 8.4.31 react: 19.2.0 react-dom: 19.2.0(react@19.2.0) styled-jsx: 5.1.6(@babel/core@7.28.5)(react@19.2.0) optionalDependencies: - '@next/swc-darwin-arm64': 16.0.0 - '@next/swc-darwin-x64': 16.0.0 - '@next/swc-linux-arm64-gnu': 16.0.0 - '@next/swc-linux-arm64-musl': 16.0.0 - '@next/swc-linux-x64-gnu': 16.0.0 - '@next/swc-linux-x64-musl': 16.0.0 - '@next/swc-win32-arm64-msvc': 16.0.0 - '@next/swc-win32-x64-msvc': 16.0.0 + '@next/swc-darwin-arm64': 16.0.1 + '@next/swc-darwin-x64': 16.0.1 + '@next/swc-linux-arm64-gnu': 16.0.1 + '@next/swc-linux-arm64-musl': 16.0.1 + '@next/swc-linux-x64-gnu': 16.0.1 + '@next/swc-linux-x64-musl': 16.0.1 + '@next/swc-win32-arm64-msvc': 16.0.1 + '@next/swc-win32-x64-msvc': 16.0.1 babel-plugin-react-compiler: 19.1.0-rc.3 sharp: 0.34.4 transitivePeerDependencies: @@ -20972,15 +20871,6 @@ snapshots: numeral@2.0.6: {} - nypm@0.5.4: - dependencies: - citty: 0.1.6 - consola: 3.4.2 - pathe: 2.0.3 - pkg-types: 1.3.1 - tinyexec: 0.3.2 - ufo: 1.6.1 - nypm@0.6.2: dependencies: citty: 0.1.6 @@ -21007,14 +20897,12 @@ snapshots: obuf@1.1.2: optional: true - ofetch@1.4.1: + ofetch@1.5.0: dependencies: destr: 2.0.5 node-fetch-native: 1.6.7 ufo: 1.6.1 - ohash@1.1.6: {} - ohash@2.0.11: {} on-change@4.0.2: {} @@ -21147,8 +21035,6 @@ snapshots: pathe@0.2.0: {} - pathe@1.1.2: {} - pathe@2.0.3: {} pbf@3.3.0: @@ -21161,8 +21047,6 @@ snapshots: dependencies: resolve-protobuf-schema: 2.1.0 - perfect-debounce@1.0.0: {} - perfect-debounce@2.0.0: {} pg-cloudflare@1.2.7: @@ -21399,7 +21283,7 @@ snapshots: dependencies: tslib: 2.8.1 - pvutils@1.1.3: {} + pvutils@1.1.5: {} quansync@0.2.11: {} @@ -21547,7 +21431,7 @@ snapshots: react: 19.2.0 react-dom: 19.2.0(react@19.2.0) - rc-field-form@2.7.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + rc-field-form@2.7.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: '@babel/runtime': 7.28.4 '@rc-component/async-validator': 5.0.4 @@ -21657,7 +21541,7 @@ snapshots: react: 19.2.0 react-dom: 19.2.0(react@19.2.0) - rc-picker@4.11.3(dayjs@1.11.18)(luxon@3.7.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + rc-picker@4.11.3(dayjs@1.11.19)(luxon@3.7.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: '@babel/runtime': 7.28.4 '@rc-component/trigger': 2.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -21668,7 +21552,7 @@ snapshots: react: 19.2.0 react-dom: 19.2.0(react@19.2.0) optionalDependencies: - dayjs: 1.11.18 + dayjs: 1.11.19 luxon: 3.7.2 rc-progress@4.0.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0): @@ -21902,7 +21786,7 @@ snapshots: react: 19.2.0 react-dom: 19.2.0(react@19.2.0) - react-i18next@16.2.0(i18next@25.6.0(typescript@5.9.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.3): + react-i18next@16.2.3(i18next@25.6.0(typescript@5.9.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.3): dependencies: '@babel/runtime': 7.28.4 html-parse-stringify: 3.0.1 @@ -21917,7 +21801,7 @@ snapshots: dependencies: react: 19.2.0 - react-intersection-observer@9.16.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + react-intersection-observer@10.0.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: react: 19.2.0 optionalDependencies: @@ -21935,15 +21819,15 @@ snapshots: transitivePeerDependencies: - supports-color - react-map-gl@8.1.0(mapbox-gl@3.13.0)(maplibre-gl@5.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + react-map-gl@8.1.0(mapbox-gl@3.13.0)(maplibre-gl@5.10.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: '@vis.gl/react-mapbox': 8.1.0(mapbox-gl@3.13.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@vis.gl/react-maplibre': 8.1.0(maplibre-gl@5.9.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@vis.gl/react-maplibre': 8.1.0(maplibre-gl@5.10.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react: 19.2.0 react-dom: 19.2.0(react@19.2.0) optionalDependencies: mapbox-gl: 3.13.0 - maplibre-gl: 5.9.0 + maplibre-gl: 5.10.0 react-markdown@10.1.0(@types/react@19.2.2)(react@19.2.0): dependencies: @@ -22012,15 +21896,15 @@ snapshots: react: 19.2.0 optional: true - react-router@7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + react-router@7.9.5(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: cookie: 1.0.2 react: 19.2.0 - set-cookie-parser: 2.7.1 + set-cookie-parser: 2.7.2 optionalDependencies: react-dom: 19.2.0(react@19.2.0) - react-scan@0.4.3(@types/react@19.2.2)(next@16.0.0(@babel/core@7.28.5)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react-router-dom@6.30.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-router@7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(rollup@2.79.2): + react-scan@0.4.3(@types/react@19.2.2)(next@16.0.1(@babel/core@7.28.5)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react-router-dom@6.30.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-router@7.9.5(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(rollup@2.79.2): dependencies: '@babel/core': 7.28.4 '@babel/generator': 7.28.3 @@ -22030,7 +21914,7 @@ snapshots: '@pivanov/utils': 0.0.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@preact/signals': 1.3.2(preact@10.27.2) '@rollup/pluginutils': 5.3.0(rollup@2.79.2) - '@types/node': 20.19.23 + '@types/node': 20.19.24 bippy: 0.3.27(@types/react@19.2.2)(react@19.2.0) esbuild: 0.25.11 estree-walker: 3.0.3 @@ -22042,8 +21926,8 @@ snapshots: react-dom: 19.2.0(react@19.2.0) tsx: 4.20.6 optionalDependencies: - next: 16.0.0(@babel/core@7.28.5)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react-router: 7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + next: 16.0.1(@babel/core@7.28.5)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + react-router: 7.9.5(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react-router-dom: 6.30.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) unplugin: 2.1.0 transitivePeerDependencies: @@ -22051,7 +21935,7 @@ snapshots: - rollup - supports-color - react-scan@0.4.3(@types/react@19.2.2)(next@16.0.0(@babel/core@7.28.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react-router-dom@6.30.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-router@7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(rollup@4.52.5): + react-scan@0.4.3(@types/react@19.2.2)(next@16.0.1(@babel/core@7.28.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react-router-dom@6.30.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-router@7.9.5(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(rollup@4.52.5): dependencies: '@babel/core': 7.28.4 '@babel/generator': 7.28.3 @@ -22061,7 +21945,7 @@ snapshots: '@pivanov/utils': 0.0.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@preact/signals': 1.3.2(preact@10.27.2) '@rollup/pluginutils': 5.3.0(rollup@4.52.5) - '@types/node': 20.19.23 + '@types/node': 20.19.24 bippy: 0.3.27(@types/react@19.2.2)(react@19.2.0) esbuild: 0.25.11 estree-walker: 3.0.3 @@ -22073,8 +21957,8 @@ snapshots: react-dom: 19.2.0(react@19.2.0) tsx: 4.20.6 optionalDependencies: - next: 16.0.0(@babel/core@7.28.5)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react-router: 7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + next: 16.0.1(@babel/core@7.28.5)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + react-router: 7.9.5(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react-router-dom: 6.30.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) unplugin: 2.1.0 transitivePeerDependencies: @@ -22407,7 +22291,7 @@ snapshots: robust-predicates@3.0.2: {} - rolldown-plugin-dts@0.16.12(rolldown@1.0.0-beta.44)(typescript@5.9.3): + rolldown-plugin-dts@0.17.3(rolldown@1.0.0-beta.45)(typescript@5.9.3): dependencies: '@babel/generator': 7.28.5 '@babel/parser': 7.28.5 @@ -22418,32 +22302,32 @@ snapshots: dts-resolver: 2.1.2 get-tsconfig: 4.13.0 magic-string: 0.30.21 - rolldown: 1.0.0-beta.44 + rolldown: 1.0.0-beta.45 optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - oxc-resolver - supports-color - rolldown@1.0.0-beta.44: + rolldown@1.0.0-beta.45: dependencies: '@oxc-project/types': 0.95.0 - '@rolldown/pluginutils': 1.0.0-beta.44 + '@rolldown/pluginutils': 1.0.0-beta.45 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-beta.44 - '@rolldown/binding-darwin-arm64': 1.0.0-beta.44 - '@rolldown/binding-darwin-x64': 1.0.0-beta.44 - '@rolldown/binding-freebsd-x64': 1.0.0-beta.44 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.44 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.44 - '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.44 - '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.44 - '@rolldown/binding-linux-x64-musl': 1.0.0-beta.44 - '@rolldown/binding-openharmony-arm64': 1.0.0-beta.44 - '@rolldown/binding-wasm32-wasi': 1.0.0-beta.44 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.44 - '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.44 - '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.44 + '@rolldown/binding-android-arm64': 1.0.0-beta.45 + '@rolldown/binding-darwin-arm64': 1.0.0-beta.45 + '@rolldown/binding-darwin-x64': 1.0.0-beta.45 + '@rolldown/binding-freebsd-x64': 1.0.0-beta.45 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.45 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.45 + '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.45 + '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.45 + '@rolldown/binding-linux-x64-musl': 1.0.0-beta.45 + '@rolldown/binding-openharmony-arm64': 1.0.0-beta.45 + '@rolldown/binding-wasm32-wasi': 1.0.0-beta.45 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.45 + '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.45 + '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.45 rollup@2.79.2: optionalDependencies: @@ -22559,7 +22443,7 @@ snapshots: server-only@0.0.1: {} - set-cookie-parser@2.7.1: {} + set-cookie-parser@2.7.2: {} set-function-length@1.2.2: dependencies: @@ -22633,14 +22517,14 @@ snapshots: shell-quote@1.8.3: {} - shiki@3.13.0: + shiki@3.14.0: dependencies: - '@shikijs/core': 3.13.0 - '@shikijs/engine-javascript': 3.13.0 - '@shikijs/engine-oniguruma': 3.13.0 - '@shikijs/langs': 3.13.0 - '@shikijs/themes': 3.13.0 - '@shikijs/types': 3.13.0 + '@shikijs/core': 3.14.0 + '@shikijs/engine-javascript': 3.14.0 + '@shikijs/engine-oniguruma': 3.14.0 + '@shikijs/langs': 3.14.0 + '@shikijs/themes': 3.14.0 + '@shikijs/types': 3.14.0 '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 @@ -23011,15 +22895,6 @@ snapshots: tapable@2.2.3: {} - tar@6.2.1: - dependencies: - chownr: 2.0.0 - fs-minipass: 2.1.0 - minipass: 5.0.0 - minizlib: 2.1.2 - mkdirp: 1.0.4 - yallist: 4.0.0 - temp-dir@2.0.0: {} tempy@0.6.0: @@ -23126,7 +23001,7 @@ snapshots: optionalDependencies: typescript: 5.9.3 - tsdown@0.15.9(typescript@5.9.3): + tsdown@0.15.12(typescript@5.9.3): dependencies: ansis: 4.2.0 cac: 6.7.14 @@ -23135,8 +23010,8 @@ snapshots: diff: 8.0.2 empathic: 2.0.0 hookable: 5.5.3 - rolldown: 1.0.0-beta.44 - rolldown-plugin-dts: 0.16.12(rolldown@1.0.0-beta.44)(typescript@5.9.3) + rolldown: 1.0.0-beta.45 + rolldown-plugin-dts: 0.17.3(rolldown@1.0.0-beta.45)(typescript@5.9.3) semver: 7.7.3 tinyexec: 1.0.1 tinyglobby: 0.2.15 @@ -23357,7 +23232,7 @@ snapshots: magic-string-ast: 1.0.3 unplugin: 2.3.10 - unplugin-dts@1.0.0-beta.6(@microsoft/api-extractor@7.52.13(@types/node@24.9.1))(esbuild@0.25.11)(rollup@4.52.5)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + unplugin-dts@1.0.0-beta.6(@microsoft/api-extractor@7.52.13(@types/node@24.9.2))(esbuild@0.25.11)(rollup@4.52.5)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.52.5) '@volar/typescript': 2.4.23 @@ -23369,10 +23244,10 @@ snapshots: typescript: 5.9.3 unplugin: 2.3.10 optionalDependencies: - '@microsoft/api-extractor': 7.52.13(@types/node@24.9.1) + '@microsoft/api-extractor': 7.52.13(@types/node@24.9.2) esbuild: 0.25.11 rollup: 4.52.5 - vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - supports-color @@ -23518,13 +23393,13 @@ snapshots: vite-bundle-analyzer@1.2.3: {} - vite-node@3.2.4(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): + vite-node@3.2.4(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: cac: 6.7.14 debug: 4.4.3(supports-color@5.5.0) es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - '@types/node' - jiti @@ -23539,12 +23414,12 @@ snapshots: - tsx - yaml - vite-plugin-babel@1.3.2(@babel/core@7.28.5)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + vite-plugin-babel@1.3.2(@babel/core@7.28.5)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: '@babel/core': 7.28.5 - vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) - vite-plugin-checker@0.11.0(eslint@9.38.0(jiti@2.6.1))(meow@13.2.0)(optionator@0.9.4)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + vite-plugin-checker@0.11.0(eslint@9.38.0(jiti@2.6.1))(meow@13.2.0)(optionator@0.9.4)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: '@babel/code-frame': 7.27.1 chokidar: 4.0.3 @@ -23553,7 +23428,7 @@ snapshots: picomatch: 4.0.3 tiny-invariant: 1.3.3 tinyglobby: 0.2.15 - vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vscode-uri: 3.1.0 optionalDependencies: eslint: 9.38.0(jiti@2.6.1) @@ -23561,7 +23436,7 @@ snapshots: optionator: 0.9.4 typescript: 5.9.3 - vite-plugin-html@3.2.2(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + vite-plugin-html@3.2.2(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: '@rollup/pluginutils': 4.2.1 colorette: 2.0.20 @@ -23575,14 +23450,14 @@ snapshots: html-minifier-terser: 6.1.0 node-html-parser: 5.4.2 pathe: 0.2.0 - vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) - vite-plugin-pwa@1.1.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(workbox-build@7.3.0(@types/babel__core@7.20.5))(workbox-window@7.3.0): + vite-plugin-pwa@1.1.0(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(workbox-build@7.3.0(@types/babel__core@7.20.5))(workbox-window@7.3.0): dependencies: debug: 4.4.3(supports-color@5.5.0) pretty-bytes: 6.1.1 tinyglobby: 0.2.15 - vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) workbox-build: 7.3.0(@types/babel__core@7.20.5) workbox-window: 7.3.0 transitivePeerDependencies: @@ -23590,18 +23465,18 @@ snapshots: vite-plugin-route-builder@0.4.1: {} - vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): + vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: debug: 4.4.3(supports-color@5.5.0) globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.9.3) optionalDependencies: - vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - supports-color - typescript - vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): + vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: esbuild: 0.25.11 fdir: 6.5.0(picomatch@4.0.3) @@ -23610,7 +23485,7 @@ snapshots: rollup: 4.52.5 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.9.1 + '@types/node': 24.9.2 fsevents: 2.3.3 jiti: 2.6.1 lightningcss: 1.30.2 @@ -23618,15 +23493,15 @@ snapshots: tsx: 4.20.6 yaml: 2.8.1 - vitest@4.0.3(@types/debug@4.1.12)(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): + vitest@4.0.6(@types/debug@4.1.12)(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: - '@vitest/expect': 4.0.3 - '@vitest/mocker': 4.0.3(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) - '@vitest/pretty-format': 4.0.3 - '@vitest/runner': 4.0.3 - '@vitest/snapshot': 4.0.3 - '@vitest/spy': 4.0.3 - '@vitest/utils': 4.0.3 + '@vitest/expect': 4.0.6 + '@vitest/mocker': 4.0.6(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + '@vitest/pretty-format': 4.0.6 + '@vitest/runner': 4.0.6 + '@vitest/snapshot': 4.0.6 + '@vitest/spy': 4.0.6 + '@vitest/utils': 4.0.6 debug: 4.4.3(supports-color@5.5.0) es-module-lexer: 1.7.0 expect-type: 1.2.2 @@ -23638,11 +23513,11 @@ snapshots: tinyexec: 0.3.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 - '@types/node': 24.9.1 + '@types/node': 24.9.2 transitivePeerDependencies: - jiti - less @@ -23895,7 +23770,8 @@ snapshots: yallist@3.1.1: {} - yallist@4.0.0: {} + yallist@4.0.0: + optional: true yaml@1.10.2: {} @@ -23944,13 +23820,13 @@ snapshots: optionalDependencies: react: 19.2.0 - zustand@5.0.8(@types/react@19.2.2)(immer@10.1.3)(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0)): + zustand@5.0.8(@types/react@19.2.2)(immer@10.2.0)(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0)): optionalDependencies: '@types/react': 19.2.2 - immer: 10.1.3 + immer: 10.2.0 react: 19.2.0 use-sync-external-store: 1.6.0(react@19.2.0) zwitch@2.0.4: {} - zx@8.8.2: {} + zx@8.8.5: {}