diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f1315c41..946c4c5ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## v1.3.7.6 STABLE + +### Fixed + +- Codemirror crash on the code editor page was fixed. by @nayskutzu +- File manager downloads now use signed Wings URLs (same as backups) instead of proxying the whole file through PHP, fixing large-file failures caused by the default 30s Guzzle/cURL timeout. by @cursor +- PBS backups no longer show **0 MiB** when snapshot-list size is missing: Wings parses logical size from `proxmox-backup-client` output. New PBS archives default to `root.pxar` (PVE-style `root.pxar.didx` in PBS UI); restore still accepts legacy `server.pxar`. by @cursor + ## v1.3.7.5 STABLE ### Added @@ -32,6 +40,7 @@ ### Fixed - Cloudflare Under Attack Mode / challenge HTML no longer clears the panel session or empties permissions (admin appearing as a normal user, owned-server access errors, console JWT failures). by @cursor +- Marketplace/cloud `.fpa` installs failing with `ADDON_EXTRACT_FAILED`: Mythic packages use AES-256 (PKZIP 5.1) while Info-ZIP `unzip` only supports ZipCrypto — extraction now uses PHP `ZipArchive` (with unzip fallback). by @cursor - Admin area stats were not loading correctly. by @nayskutzu - Fixed the issue with unlimited backup limit. by @nayskutzu - Issues related to port allocation were fixed. by @nayskutzu diff --git a/app b/app index 6cbc1e825..9b3319cac 100755 --- a/app +++ b/app @@ -48,7 +48,7 @@ define('APP_ADDONS_DIR', APP_STORAGE_DIR . 'addons'); define('APP_SOURCECODE_DIR', APP_DIR . 'app'); define('APP_ROUTES_DIR', APP_SOURCECODE_DIR . '/Api'); define('SYSTEM_KERNEL_NAME', php_uname('s')); -define('APP_VERSION', 'v1.3.7.5'); +define('APP_VERSION', 'v1.3.7.6'); define('APP_UPSTREAM', 'stable'); define('TELEMETRY', true); define('IS_CLI', true); diff --git a/backend/app/Controllers/Admin/CloudPluginsController.php b/backend/app/Controllers/Admin/CloudPluginsController.php index f9ed74c27..c3c6c284f 100755 --- a/backend/app/Controllers/Admin/CloudPluginsController.php +++ b/backend/app/Controllers/Admin/CloudPluginsController.php @@ -24,6 +24,7 @@ use App\Chat\InstalledPlugin; use OpenApi\Attributes as OA; use App\Helpers\PanelAssetUrl; +use App\Helpers\AddonPackageHelper; use App\CloudFlare\CloudFlareRealIP; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -904,14 +905,11 @@ public function install(Request $request): Response $tempFile = sys_get_temp_dir() . '/' . uniqid('featherpanel_', true) . '.fpa'; file_put_contents($tempFile, $fileContent); - // Extract + // Extract (ZipArchive: AES marketplace packages + legacy ZipCrypto) $tempDir = sys_get_temp_dir() . '/' . uniqid('featherpanel_', true); - @mkdir($tempDir, 0755, true); - $pwd = self::PASSWORD; - $unzipCommand = sprintf('unzip -P %s %s -d %s', escapeshellarg($pwd), escapeshellarg($tempFile), escapeshellarg($tempDir)); - exec($unzipCommand, $out, $code); + $extracted = AddonPackageHelper::extract($tempFile, $tempDir, self::PASSWORD); @unlink($tempFile); - if ($code !== 0) { + if (!$extracted) { @exec('rm -rf ' . escapeshellarg($tempDir)); return ApiResponse::error('Failed to extract addon package', 'ADDON_EXTRACT_FAILED', 422); @@ -1330,12 +1328,9 @@ private function evaluateConfDependencyChecksFromBinary(string $fileContent): ar file_put_contents($tempFile, $fileContent); $tempDir = sys_get_temp_dir() . '/' . uniqid('featherpanel_check_', true); - @mkdir($tempDir, 0755, true); - $pwd = self::PASSWORD; - $unzipCommand = sprintf('unzip -P %s %s conf.yml -d %s', escapeshellarg($pwd), escapeshellarg($tempFile), escapeshellarg($tempDir)); - exec($unzipCommand, $out, $code); + $extracted = AddonPackageHelper::extract($tempFile, $tempDir, self::PASSWORD, ['conf.yml']); - if ($code === 0 && file_exists($tempDir . '/conf.yml')) { + if ($extracted && file_exists($tempDir . '/conf.yml')) { try { $conf = \Symfony\Component\Yaml\Yaml::parseFile($tempDir . '/conf.yml'); $confDependencies = $conf['plugin']['dependencies'] ?? []; diff --git a/backend/app/Controllers/Admin/PluginsController.php b/backend/app/Controllers/Admin/PluginsController.php index 6fc466c66..99c1ad203 100755 --- a/backend/app/Controllers/Admin/PluginsController.php +++ b/backend/app/Controllers/Admin/PluginsController.php @@ -23,6 +23,7 @@ use App\Chat\InstalledPlugin; use App\Plugins\PluginConfig; use OpenApi\Attributes as OA; +use App\Helpers\AddonPackageHelper; use App\Helpers\PanelAssetUrl; use App\Config\ConfigInterface; use App\Plugins\PluginSettings; @@ -742,14 +743,11 @@ public function uploadInstall(Request $request): Response $tempFile = sys_get_temp_dir() . '/' . uniqid('featherpanel_', true) . '.fpa'; $file->move(dirname($tempFile), basename($tempFile)); - // Extract + // Extract (ZipArchive: AES marketplace packages + legacy ZipCrypto) $tempDir = sys_get_temp_dir() . '/' . uniqid('featherpanel_', true); - @mkdir($tempDir, 0755, true); - $pwd = CloudPluginsController::PASSWORD; - $unzipCommand = sprintf('unzip -P %s %s -d %s', escapeshellarg($pwd), escapeshellarg($tempFile), escapeshellarg($tempDir)); - exec($unzipCommand, $out, $code); + $extracted = AddonPackageHelper::extract($tempFile, $tempDir, CloudPluginsController::PASSWORD); @unlink($tempFile); - if ($code !== 0) { + if (!$extracted) { @exec('rm -rf ' . escapeshellarg($tempDir)); return ApiResponse::error('Failed to extract addon package', 'ADDON_EXTRACT_FAILED', 422); @@ -818,12 +816,9 @@ public function uploadInstallFromUrl(Request $request): Response file_put_contents($tempFile, $fileContent); $tempDir = sys_get_temp_dir() . '/' . uniqid('featherpanel_', true); - @mkdir($tempDir, 0755, true); - $pwd = CloudPluginsController::PASSWORD; - $unzipCommand = sprintf('unzip -P %s %s -d %s', escapeshellarg($pwd), escapeshellarg($tempFile), escapeshellarg($tempDir)); - exec($unzipCommand, $out, $code); + $extracted = AddonPackageHelper::extract($tempFile, $tempDir, CloudPluginsController::PASSWORD); @unlink($tempFile); - if ($code !== 0) { + if (!$extracted) { @exec('rm -rf ' . escapeshellarg($tempDir)); return ApiResponse::error('Failed to extract addon package', 'ADDON_EXTRACT_FAILED', 422); diff --git a/backend/app/Controllers/User/Server/Files/ServerFilesController.php b/backend/app/Controllers/User/Server/Files/ServerFilesController.php index c50481011..ad756f7e5 100755 --- a/backend/app/Controllers/User/Server/Files/ServerFilesController.php +++ b/backend/app/Controllers/User/Server/Files/ServerFilesController.php @@ -22,7 +22,10 @@ use App\SubuserPermissions; use App\Chat\ServerActivity; use App\Helpers\ApiResponse; +use App\Helpers\AppUrlHelper; +use App\Helpers\WingsUrlHelper; use App\Services\Wings\Wings; +use App\Services\Wings\Services\JwtService; use OpenApi\Attributes as OA; use App\Config\ConfigInterface; use App\Plugins\Events\Events\ServerEvent; @@ -2107,8 +2110,8 @@ public function uploadFile(Request $request, string $serverUuid): Response #[OA\Get( path: '/api/user/servers/{uuidShort}/download-file', - summary: 'Download file', - description: 'Download a file from the server with appropriate headers for file download.', + summary: 'Get file download URL', + description: 'Generate a secure one-time Wings download URL for a server file with JWT token authentication (same pattern as backup downloads).', tags: ['User - Server Files'], parameters: [ new OA\Parameter( @@ -2129,39 +2132,19 @@ public function uploadFile(Request $request, string $serverUuid): Response responses: [ new OA\Response( response: 200, - description: 'File downloaded successfully', - content: new OA\MediaType( - mediaType: 'application/octet-stream', - schema: new OA\Schema(type: 'string', format: 'binary') - ), - headers: [ - new OA\Header( - header: 'Content-Type', - description: 'MIME type of the file', - schema: new OA\Schema(type: 'string', example: 'text/plain') - ), - new OA\Header( - header: 'Content-Disposition', - description: 'Download attachment header', - schema: new OA\Schema(type: 'string', example: 'attachment; filename="file.txt"') - ), - new OA\Header( - header: 'Content-Length', - description: 'File size in bytes', - schema: new OA\Schema(type: 'string', example: '1024') - ), - new OA\Header( - header: 'Cache-Control', - description: 'Cache control header', - schema: new OA\Schema(type: 'string', example: 'no-cache, no-store, must-revalidate') - ), - ] + description: 'Download URL generated successfully', + content: new OA\JsonContent( + properties: [ + new OA\Property(property: 'download_url', type: 'string', description: 'Signed Wings file download URL'), + new OA\Property(property: 'expires_in', type: 'integer', description: 'Token lifetime in seconds', example: 300), + ] + ) ), new OA\Response(response: 400, description: 'Bad request - Missing UUID or file path'), new OA\Response(response: 401, description: 'Unauthorized - User not authenticated'), new OA\Response(response: 403, description: 'Forbidden - Access denied to server'), new OA\Response(response: 404, description: 'Not found - Server, node, or file not found'), - new OA\Response(response: 500, description: 'Internal server error - Failed to download file'), + new OA\Response(response: 500, description: 'Internal server error - Failed to generate download URL'), ] )] public function downloadFile(Request $request, string $serverUuid): Response @@ -2183,56 +2166,30 @@ public function downloadFile(Request $request, string $serverUuid): Response } $node = $this->validateNode($server['node_id']); + $filename = basename($path); - $wings = $this->createWingsConnection($node); - - // Use the download method to get raw file content - $response = $wings->getServer()->downloadFile($server['uuid'], $path); - - if (!$response->isSuccessful()) { - $error = $response->getError(); - - return ApiResponse::error('Failed to download file: ' . $error, 'WINGS_ERROR', $response->getStatusCode()); - } - - // Get the raw file content - $fileContent = $response->getRawBody(); - - // Empty files are valid - only return error if content is null (indicating an actual error) - // If fileContent is null (not just empty string), it might indicate an error - if ($fileContent === null) { - // Check if response indicates an error - $responseData = $response->getData(); - if (is_array($responseData) && (isset($responseData['error']) || isset($responseData['error_message']))) { - return ApiResponse::error('File content could not be retrieved', 'FILE_CONTENT_ERROR', 500); - } - // If no error indicated, treat as empty file - $fileContent = ''; - } + $token = $node['daemon_token']; + $wingsBaseUrl = WingsUrlHelper::buildFromNode($node); - // Get filename from path - $filename = basename($path); + $jwtService = new JwtService( + $token, + AppUrlHelper::wingsRemoteUrl(), + $wingsBaseUrl + ); - // Determine content type based on file extension - $contentType = $this->getMimeType($path); + $jwtToken = $jwtService->generateFileDownloadToken($server['uuid'], $path); + $baseUrl = rtrim($wingsBaseUrl, '/'); + $encodedFilePath = urlencode($path); + $downloadUrl = "{$baseUrl}/download/file?token={$jwtToken}&server={$server['uuid']}&file={$encodedFilePath}"; - // Log activity $this->logActivity($server, $node, 'file_downloaded', [ 'path' => $path, 'filename' => $filename, - - 'file_size' => strlen($fileContent), - 'content_type' => $contentType, ], $user); - // Return file content with download headers - return new Response($fileContent, 200, [ - 'Content-Type' => $contentType, - 'Content-Disposition' => 'attachment; filename="' . $filename . '"', - 'Content-Length' => strlen($fileContent), - 'Cache-Control' => 'no-cache, no-store, must-revalidate', - 'Pragma' => 'no-cache', - 'Expires' => '0', + return ApiResponse::success([ + 'download_url' => $downloadUrl, + 'expires_in' => 300, ]); } catch (\Exception $e) { return $this->handleWingsError($e, 'download file'); diff --git a/backend/app/Helpers/AddonPackageHelper.php b/backend/app/Helpers/AddonPackageHelper.php new file mode 100644 index 000000000..c736677ee --- /dev/null +++ b/backend/app/Helpers/AddonPackageHelper.php @@ -0,0 +1,104 @@ +. + */ + +namespace App\Helpers; + +/** + * Extract password-protected .fpa addon packages. + * + * Marketplace packages from Mythic are re-encrypted with AES-256 (PKZIP 5.1). + * Info-ZIP `unzip` only supports traditional ZipCrypto (PKZIP ≤ 4.6), so extraction + * must use PHP ZipArchive (libzip), which handles both AES and ZipCrypto. + */ +class AddonPackageHelper +{ + /** + * Extract a .fpa archive into a destination directory. + * + * @param string $archivePath Path to the .fpa / zip file + * @param string $destinationDir Directory to extract into (created if missing) + * @param string $password Archive password + * @param list|null $entries Optional subset of entries to extract (e.g. ['conf.yml']) + */ + public static function extract(string $archivePath, string $destinationDir, string $password, ?array $entries = null): bool + { + if (!is_file($archivePath)) { + return false; + } + + if (!is_dir($destinationDir) && !@mkdir($destinationDir, 0755, true)) { + return false; + } + + if (self::extractWithZipArchive($archivePath, $destinationDir, $password, $entries)) { + return true; + } + + // Fallback for legacy ZipCrypto packages if ZipArchive is unavailable/broken + return self::extractWithUnzip($archivePath, $destinationDir, $password, $entries); + } + + /** + * @param list|null $entries + */ + private static function extractWithZipArchive(string $archivePath, string $destinationDir, string $password, ?array $entries): bool + { + if (!class_exists(\ZipArchive::class)) { + return false; + } + + $zip = new \ZipArchive(); + if ($zip->open($archivePath) !== true) { + return false; + } + + if ($password !== '') { + $zip->setPassword($password); + } + + $ok = $entries === null || $entries === [] + ? $zip->extractTo($destinationDir) + : $zip->extractTo($destinationDir, $entries); + + $zip->close(); + + return $ok === true; + } + + /** + * @param list|null $entries + */ + private static function extractWithUnzip(string $archivePath, string $destinationDir, string $password, ?array $entries): bool + { + $entryArgs = ''; + if ($entries !== null && $entries !== []) { + $entryArgs = ' ' . implode(' ', array_map('escapeshellarg', $entries)); + } + + $unzipCommand = sprintf( + 'unzip -P %s %s%s -d %s', + escapeshellarg($password), + escapeshellarg($archivePath), + $entryArgs, + escapeshellarg($destinationDir) + ); + + exec($unzipCommand, $out, $code); + + return $code === 0; + } +} diff --git a/backend/app/Services/Wings/Services/JwtService.php b/backend/app/Services/Wings/Services/JwtService.php index b9e17b4a7..40dc04219 100755 --- a/backend/app/Services/Wings/Services/JwtService.php +++ b/backend/app/Services/Wings/Services/JwtService.php @@ -184,6 +184,21 @@ public function generateBackupToken( ); } + /** + * Generate a one-time JWT token for direct Wings file downloads. + * + * @param string $serverUuid The server UUID + * @param string $filePath The file path on the server + * + * @throws \Exception + * + * @return string The JWT token + */ + public function generateFileDownloadToken(string $serverUuid, string $filePath): string + { + return $this->tokenGenerator->generateFileDownloadToken($serverUuid, $filePath); + } + /** * Generate a JWT token for file operations. * diff --git a/backend/cli b/backend/cli index 73ba431c5..42be8e3f8 100755 --- a/backend/cli +++ b/backend/cli @@ -42,7 +42,7 @@ define('APP_START', microtime(true)); define('APP_DIR', APP_PUBLIC . '/'); define('APP_CRON_DIR', APP_PUBLIC . '/storage/cron/'); define('SYSTEM_KERNEL_NAME', php_uname('s')); -define('APP_VERSION', 'v1.3.7.5'); +define('APP_VERSION', 'v1.3.7.6'); define('APP_UPSTREAM', 'stable'); define('REQUEST_ID', uniqid()); define('TELEMETRY', true); diff --git a/backend/public/index.php b/backend/public/index.php index 7376cf24f..52384c610 100755 --- a/backend/public/index.php +++ b/backend/public/index.php @@ -34,7 +34,7 @@ define('SYSTEM_OS_NAME', gethostname() . '/' . PHP_OS_FAMILY); define('SYSTEM_KERNEL_NAME', php_uname('s')); define('TELEMETRY', true); -define('APP_VERSION', 'v1.3.7.5'); +define('APP_VERSION', 'v1.3.7.6'); define('APP_UPSTREAM', 'stable'); define('REQUEST_ID', uniqid()); diff --git a/backend/storage/addons/.last-release-version b/backend/storage/addons/.last-release-version index 45a1b3f44..227cea215 100644 --- a/backend/storage/addons/.last-release-version +++ b/backend/storage/addons/.last-release-version @@ -1 +1 @@ -1.1.2 +2.0.0 diff --git a/frontendv2/.ncurc.json b/frontendv2/.ncurc.json index ee8c16404..efce110c2 100644 --- a/frontendv2/.ncurc.json +++ b/frontendv2/.ncurc.json @@ -1,4 +1,6 @@ { - "upgrade": true, - "reject": ["eslint", "typescript"] + "upgrade": true, + "reject": [ + "eslint" + ] } diff --git a/frontendv2/eslint.config.mjs b/frontendv2/eslint.config.mjs index 84a795a03..bcc383cc4 100644 --- a/frontendv2/eslint.config.mjs +++ b/frontendv2/eslint.config.mjs @@ -51,6 +51,8 @@ const eslintConfig = defineConfig([ 'next-env.d.ts', // Ignore generated documentation files 'src/app/(docs)/**', + // CJS preload for TypeScript 7 + typescript-eslint side-by-side + 'scripts/eslint-ts6-shim.cjs', ]), ]); diff --git a/frontendv2/next.config.ts b/frontendv2/next.config.ts index 1846bf5b3..668df902a 100644 --- a/frontendv2/next.config.ts +++ b/frontendv2/next.config.ts @@ -26,10 +26,23 @@ const nextConfig: NextConfig = { experimental: { // Filesystem cache balloons RAM on large apps; use webpack dev by default instead. - turbopackFileSystemCacheForDev: false, + turbopackFileSystemCacheForDev: true, + // TypeScript 7 has no programmatic compiler API; Next must shell out to `tsc`. + useTypeScriptCli: true, }, webpack: (config: WebpackConfiguration, { dev }) => { + // Keep a single physical CodeMirror copy if webpack resolves nested deps differently. + config.resolve = config.resolve ?? {}; + config.resolve.alias = { + ...(typeof config.resolve.alias === 'object' && !Array.isArray(config.resolve.alias) + ? config.resolve.alias + : {}), + '@codemirror/state': path.resolve(__dirname, 'node_modules/@codemirror/state'), + '@codemirror/view': path.resolve(__dirname, 'node_modules/@codemirror/view'), + '@codemirror/language': path.resolve(__dirname, 'node_modules/@codemirror/language'), + }; + if (dev) { // Keep dev compilation single-threaded to avoid spawning many hungry workers. config.parallelism = 1; diff --git a/frontendv2/package.json b/frontendv2/package.json index 8e1ea4f62..dcb5650f7 100644 --- a/frontendv2/package.json +++ b/frontendv2/package.json @@ -11,7 +11,7 @@ "build:next": "next build", "start": "next start", "lint": "run-s lint:eslint lint:format", - "lint:eslint": "eslint --fix", + "lint:eslint": "node --require ./scripts/eslint-ts6-shim.cjs ./node_modules/eslint/bin/eslint.js --fix", "lint:format": "prettier --log-level silent --write src/", "format": "run-s lint:format", "scan:translations": "node scripts/scan-translations.js", @@ -36,7 +36,7 @@ "@codemirror/legacy-modes": "^6.5.3", "@codemirror/state": "^6.7.1", "@codemirror/theme-one-dark": "^6.1.3", - "@codemirror/view": "^6.43.6", + "@codemirror/view": "^6.43.7", "@hcaptcha/react-hcaptcha": "^2.0.2", "@headlessui/react": "^2.2.10", "@monaco-editor/react": "4.8.0-rc.3", @@ -45,7 +45,7 @@ "@radix-ui/react-switch": "^1.3.7", "@radix-ui/react-tabs": "^1.1.21", "@react-three/drei": "^10.7.7", - "@react-three/fiber": "^9.6.1", + "@react-three/fiber": "^9.7.0", "@simplewebauthn/browser": "13.3.0", "@tailwindcss/typography": "^0.5.20", "@types/js-yaml": "^4.0.9", @@ -59,13 +59,13 @@ "@xterm/addon-web-links": "^0.12.0", "@xterm/addon-webgl": "^0.19.0", "@xterm/xterm": "^6.0.0", - "axios": "^1.18.1", + "axios": "^1.19.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "date-fns": "^4.4.0", "date-fns-tz": "^3.2.0", - "js-yaml": "^5.2.2", - "lucide-react": "^1.27.0", + "js-yaml": "^5.2.3", + "lucide-react": "^1.28.0", "next": "16.2.12", "ogl": "^1.0.11", "prettier": "^3.9.6", @@ -88,6 +88,7 @@ "@types/node": "^26", "@types/react": "^19", "@types/react-dom": "^19", + "@typescript/typescript6": "^6.0.2", "babel-plugin-react-compiler": "1.0.0", "eslint": "^9", "eslint-config-next": "16.2.12", @@ -95,7 +96,7 @@ "npm-run-all": "^4.1.5", "prettier-plugin-tailwindcss": "^0.8.1", "tailwindcss": "^4", - "typescript": "^6.0.3" + "typescript": "^7.0.2" }, - "packageManager": "pnpm@11.17.0" + "packageManager": "pnpm@11.18.0" } diff --git a/frontendv2/pnpm-lock.yaml b/frontendv2/pnpm-lock.yaml index 70a16571a..64614a1df 100644 --- a/frontendv2/pnpm-lock.yaml +++ b/frontendv2/pnpm-lock.yaml @@ -4,6 +4,11 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + '@codemirror/state': 6.7.1 + '@codemirror/view': 6.43.7 + '@codemirror/language': 6.12.4 + importers: .: @@ -30,20 +35,20 @@ importers: specifier: ^6.1.3 version: 6.1.3 '@codemirror/language': - specifier: ^6.12.4 + specifier: 6.12.4 version: 6.12.4 '@codemirror/legacy-modes': specifier: ^6.5.3 version: 6.5.3 '@codemirror/state': - specifier: ^6.7.1 + specifier: 6.7.1 version: 6.7.1 '@codemirror/theme-one-dark': specifier: ^6.1.3 version: 6.1.3 '@codemirror/view': - specifier: ^6.43.6 - version: 6.43.6 + specifier: 6.43.7 + version: 6.43.7 '@hcaptcha/react-hcaptcha': specifier: ^2.0.2 version: 2.0.2 @@ -67,10 +72,10 @@ importers: version: 1.1.21(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@react-three/drei': specifier: ^10.7.7 - version: 10.7.7(@react-three/fiber@9.6.1(@types/react@19.2.14)(immer@11.1.15)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(three@0.185.1))(@types/react@19.2.14)(@types/three@0.184.1)(immer@11.1.15)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(three@0.185.1) + version: 10.7.7(@react-three/fiber@9.7.0(@types/react@19.2.14)(immer@11.1.15)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(three@0.185.1))(@types/react@19.2.14)(@types/three@0.184.1)(immer@11.1.15)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(three@0.185.1) '@react-three/fiber': - specifier: ^9.6.1 - version: 9.6.1(@types/react@19.2.14)(immer@11.1.15)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(three@0.185.1) + specifier: ^9.7.0 + version: 9.7.0(@types/react@19.2.14)(immer@11.1.15)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(three@0.185.1) '@simplewebauthn/browser': specifier: 13.3.0 version: 13.3.0 @@ -85,7 +90,7 @@ importers: version: 2.1.9 '@uiw/react-codemirror': specifier: ^4.25.11 - version: 4.25.11(@babel/runtime@7.29.2)(@codemirror/autocomplete@6.20.3)(@codemirror/language@6.12.4)(@codemirror/lint@6.9.7)(@codemirror/search@6.7.1)(@codemirror/state@6.7.1)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.43.6)(codemirror@6.0.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + version: 4.25.11(@babel/runtime@7.29.2)(@codemirror/autocomplete@6.20.3)(@codemirror/language@6.12.4)(@codemirror/lint@6.9.7)(@codemirror/search@6.7.1)(@codemirror/state@6.7.1)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.43.7)(codemirror@6.0.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@xterm/addon-attach': specifier: ^0.12.0 version: 0.12.0 @@ -111,8 +116,8 @@ importers: specifier: ^6.0.0 version: 6.0.0 axios: - specifier: ^1.18.1 - version: 1.18.1(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0) + specifier: ^1.19.0 + version: 1.19.0(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -126,11 +131,11 @@ importers: specifier: ^3.2.0 version: 3.2.0(date-fns@4.4.0) js-yaml: - specifier: ^5.2.2 - version: 5.2.2 + specifier: ^5.2.3 + version: 5.2.3 lucide-react: - specifier: ^1.27.0 - version: 1.27.0(react@19.2.8) + specifier: ^1.28.0 + version: 1.28.0(react@19.2.8) next: specifier: 16.2.12 version: 16.2.12(@babel/core@7.29.0(supports-color@7.2.0))(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) @@ -192,18 +197,21 @@ importers: '@types/react-dom': specifier: ^19 version: 19.2.3(@types/react@19.2.14) + '@typescript/typescript6': + specifier: ^6.0.2 + version: 6.0.2 babel-plugin-react-compiler: specifier: 1.0.0 version: 1.0.0 eslint: specifier: ^9 - version: 9.39.4(jiti@2.7.0)(supports-color@7.2.0) + version: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) eslint-config-next: specifier: 16.2.12 - version: 16.2.12(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) + version: 16.2.12(@typescript-eslint/parser@8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2))(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0)) + version: 10.1.8(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)) npm-run-all: specifier: ^4.1.5 version: 4.1.5 @@ -214,8 +222,8 @@ importers: specifier: ^4 version: 4.2.4 typescript: - specifier: ^6.0.3 - version: 6.0.3 + specifier: ^7.0.2 + version: 7.0.2 packages: @@ -321,9 +329,6 @@ packages: '@codemirror/lang-yaml@6.1.3': resolution: {integrity: sha512-AZ8DJBuXGVHybpBQhmZtgew5//4hv3tdkXnr3vDmOUMJRuB6vn/uuwtmTOTlqEaQFg3hQSVeA90NmvIQyUV6FQ==} - '@codemirror/language@6.12.3': - resolution: {integrity: sha512-QwCZW6Tt1siP37Jet9Tb02Zs81TQt6qQrZR2H+eGMcFsL1zMrk2/b9CLC7/9ieP1fjIUMgviLWMmgiHoJrj+ZA==} - '@codemirror/language@6.12.4': resolution: {integrity: sha512-1q4PaT+o6PbgpkJt4Q8Fv5XJxTy4FUZ4MWETtyiDw3J0Pyr9E2vqcKL+k9wcvjNTIsauxvE7OfmWj3FRPHQ76A==} @@ -336,20 +341,14 @@ packages: '@codemirror/search@6.7.1': resolution: {integrity: sha512-uMe5UO6PamJtSHrXhhHOzSX3ReWtiJrva6GnPMwSOrZtiExb5X5eExhr2OUZQVvdxPsKpY3Ro2mFbQadpPWmHA==} - '@codemirror/state@6.7.0': - resolution: {integrity: sha512-Zbl9NyscLMZkfXPQnNAIIAFftidrA1UbcJEIMp24C0Bukc2I5T8wJS0wsXYsnDOqCFJUeJ1BITGNs5CqPDSmSg==} - '@codemirror/state@6.7.1': resolution: {integrity: sha512-9QzNDgE4EYDnAHfrTlR2lwiPciiOymLtwKK+8yHQzCc7GXhAP9xdEbEJFy2IWB1j9UGUl9BsgMmTo/ImA02T7A==} '@codemirror/theme-one-dark@6.1.3': resolution: {integrity: sha512-NzBdIvEJmx6fjeremiGp3t/okrLPYT0d9orIc7AFun8oZcRk58aejkqhv6spnz4MLAevrKNPMQYXEWMg4s+sKA==} - '@codemirror/view@6.43.2': - resolution: {integrity: sha512-8kU6WNRYBKV9Sw3cxNz+uSvUvx3tt+1qgupGFPubnbLFDHOgh5qQdIGmXcD7bkA/PROK6LDKVhKMpcY7H++Amg==} - - '@codemirror/view@6.43.6': - resolution: {integrity: sha512-EVunGSYN1wz1p75WY1s3Xg7t3i8Yol0kGZGizNdX9BUFgMFILYVe8/u6EVpo7Ff5PwbZuILb4QAq7IZoKzIEQA==} + '@codemirror/view@6.43.7': + resolution: {integrity: sha512-FZsExxkoxnAN+d9TgqXLg5g4A1oQwzX9WlkOT5i2PKkcW7xx3Bmu0vs90g6fo9Mpdsb/l96dnAraQ8932aO4/g==} '@csstools/css-calc@2.1.2': resolution: {integrity: sha512-TklMyb3uBB28b5uQdxjReG4L80NxAqgrECqLZFQbyLekwwlcDDS8r3f07DKqeo8C4926Br0gf/ZDe17Zv4wIuw==} @@ -409,12 +408,12 @@ packages: resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/eslintrc@3.3.5': - resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} + '@eslint/eslintrc@3.3.6': + resolution: {integrity: sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.39.4': - resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} + '@eslint/js@9.39.5': + resolution: {integrity: sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.7': @@ -1004,8 +1003,8 @@ packages: react-dom: optional: true - '@react-three/fiber@9.6.1': - resolution: {integrity: sha512-zF0rsKcVYpcJwbFEnv2HkHX9cvOEgsfQo/X8lwmR2dn13S4qEQJXir9fxf5js2LQFoXqxOY7MDkOkYx2uZ4gSg==} + '@react-three/fiber@9.7.0': + resolution: {integrity: sha512-EWm9FwcaOZQu/ExFW5rggoCMM1NJet5YbxVxKaOE+KSncrjU0Wx7017qSyGFvupviK89nMYGCWU3BIK4dI1clw==} peerDependencies: expo: '>=43.0' expo-asset: '>=8.4' @@ -1346,24 +1345,148 @@ packages: resolution: {integrity: sha512-NwjLUnGy8/Zfx23fl50tRC8rYaYnM52xNRYFAXvmiil9yh1+K6aRVQMnzW6gQB/1DLgWt977lYQn7C+wtgXZiA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript/typescript-aix-ppc64@7.0.2': + resolution: {integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [aix] + + '@typescript/typescript-darwin-arm64@7.0.2': + resolution: {integrity: sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [darwin] + + '@typescript/typescript-darwin-x64@7.0.2': + resolution: {integrity: sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [darwin] + + '@typescript/typescript-freebsd-arm64@7.0.2': + resolution: {integrity: sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [freebsd] + + '@typescript/typescript-freebsd-x64@7.0.2': + resolution: {integrity: sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [freebsd] + + '@typescript/typescript-linux-arm64@7.0.2': + resolution: {integrity: sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [linux] + + '@typescript/typescript-linux-arm@7.0.2': + resolution: {integrity: sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==} + engines: {node: '>=16.20.0'} + cpu: [arm] + os: [linux] + + '@typescript/typescript-linux-loong64@7.0.2': + resolution: {integrity: sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==} + engines: {node: '>=16.20.0'} + cpu: [loong64] + os: [linux] + + '@typescript/typescript-linux-mips64el@7.0.2': + resolution: {integrity: sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==} + engines: {node: '>=16.20.0'} + cpu: [mips64el] + os: [linux] + + '@typescript/typescript-linux-ppc64@7.0.2': + resolution: {integrity: sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [linux] + + '@typescript/typescript-linux-riscv64@7.0.2': + resolution: {integrity: sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==} + engines: {node: '>=16.20.0'} + cpu: [riscv64] + os: [linux] + + '@typescript/typescript-linux-s390x@7.0.2': + resolution: {integrity: sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==} + engines: {node: '>=16.20.0'} + cpu: [s390x] + os: [linux] + + '@typescript/typescript-linux-x64@7.0.2': + resolution: {integrity: sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [linux] + + '@typescript/typescript-netbsd-arm64@7.0.2': + resolution: {integrity: sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [netbsd] + + '@typescript/typescript-netbsd-x64@7.0.2': + resolution: {integrity: sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [netbsd] + + '@typescript/typescript-openbsd-arm64@7.0.2': + resolution: {integrity: sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [openbsd] + + '@typescript/typescript-openbsd-x64@7.0.2': + resolution: {integrity: sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [openbsd] + + '@typescript/typescript-sunos-x64@7.0.2': + resolution: {integrity: sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [sunos] + + '@typescript/typescript-win32-arm64@7.0.2': + resolution: {integrity: sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [win32] + + '@typescript/typescript-win32-x64@7.0.2': + resolution: {integrity: sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [win32] + + '@typescript/typescript6@6.0.2': + resolution: {integrity: sha512-mbCddXd+jm7hfx7w2YU64/Av4/NqqeG3GoRZgxPcgoTxYjhrcfJRw9ULch71SS4G+Q3bOXFhRvPqjguN0Hyp5w==} + hasBin: true + '@uiw/codemirror-extensions-basic-setup@4.25.11': resolution: {integrity: sha512-otyFa+n9IOYtEjaKOxPedHkj15fTPUF21wdR9pv0GpZPfuGl27cvmcv6+tognbRu9VvEcsHKE+ESoszeo3KfTw==} peerDependencies: '@codemirror/autocomplete': '>=6.0.0' '@codemirror/commands': '>=6.0.0' - '@codemirror/language': '>=6.0.0' + '@codemirror/language': 6.12.4 '@codemirror/lint': '>=6.0.0' '@codemirror/search': '>=6.0.0' - '@codemirror/state': '>=6.0.0' - '@codemirror/view': '>=6.0.0' + '@codemirror/state': 6.7.1 + '@codemirror/view': 6.43.7 '@uiw/react-codemirror@4.25.11': resolution: {integrity: sha512-DYVFAKLX+F/4JS9N/7xexh+TICrlncwkX9HKKInrP1bwO0tSfc3k0GB6oawTYhelVKh20cX3TuRx+NJSkVXuMw==} peerDependencies: '@babel/runtime': '>=7.11.0' - '@codemirror/state': '>=6.0.0' + '@codemirror/state': 6.7.1 '@codemirror/theme-one-dark': '>=6.0.0' - '@codemirror/view': '>=6.0.0' + '@codemirror/view': 6.43.7 codemirror: '>=6.0.0' react: '>=17.0.0' react-dom: '>=17.0.0' @@ -1592,8 +1715,8 @@ packages: resolution: {integrity: sha512-KunSNx+TVpkAw/6ULfhnx+HWRecjqZGTOyquAoWHYLRSdK1tB5Ihce1ZW+UY3fj33bYAFWPu7W/GRSmmrCGuxA==} engines: {node: '>=4'} - axios@1.18.1: - resolution: {integrity: sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==} + axios@1.19.0: + resolution: {integrity: sha512-ht/iuYZXEjFxLH/Hkezgd7m6JKlHHXEUSneaDz8uZe1Gj5QZtCnpyDsckvAiEnT89OEbCLmnte4R4sn7P0EKFw==} axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} @@ -2064,8 +2187,8 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@9.39.4: - resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} + eslint@9.39.5: + resolution: {integrity: sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -2166,8 +2289,8 @@ packages: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} - form-data@4.0.5: - resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + form-data@4.0.6: + resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==} engines: {node: '>= 6'} function-bind@1.1.2: @@ -2267,6 +2390,10 @@ packages: resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} engines: {node: '>= 0.4'} + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + hast-util-to-jsx-runtime@2.3.6: resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} @@ -2499,12 +2626,12 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-yaml@4.2.0: - resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==} + js-yaml@4.3.0: + resolution: {integrity: sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==} hasBin: true - js-yaml@5.2.2: - resolution: {integrity: sha512-dayzUzKkJ1MkuUtZglSebU43utNXH0OWQByK9rKOOuYIO8M5TV1y+n8ALMdG0rdzBnfNkOmZEqrURepb0ejqBw==} + js-yaml@5.2.3: + resolution: {integrity: sha512-n+mUVyUX5bVv7G/G2zyIHOhdxfuU1dY2NOFzTQUWiMUbFss8b57NFlgCCaggU78wSw5KVS9cllzeLyzyR+n5nw==} hasBin: true jsesc@3.1.0: @@ -2652,8 +2779,8 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lucide-react@1.27.0: - resolution: {integrity: sha512-rJicGl/3Fly/E0rOH1YmPZ6e49JCnKknh1ox1vpHnkfjujAkKA6sqUZvH3MTAaXXjgexyUwgNwTJzTtYuAFYJw==} + lucide-react@1.28.0: + resolution: {integrity: sha512-fARAFJULsGuDDydjp6+6blekG/sBIM29TerzLjc9bQUKAcEfrSc4ZQKb25KRz4OMKd87cZTb5dgq0w/T6KufVg==} peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -3596,6 +3723,11 @@ packages: engines: {node: '>=14.17'} hasBin: true + typescript@7.0.2: + resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==} + engines: {node: '>=16.20.0'} + hasBin: true + unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} @@ -3880,14 +4012,14 @@ snapshots: dependencies: '@codemirror/language': 6.12.4 '@codemirror/state': 6.7.1 - '@codemirror/view': 6.43.6 + '@codemirror/view': 6.43.7 '@lezer/common': 1.5.2 '@codemirror/commands@6.10.3': dependencies: - '@codemirror/language': 6.12.3 - '@codemirror/state': 6.7.0 - '@codemirror/view': 6.43.2 + '@codemirror/language': 6.12.4 + '@codemirror/state': 6.7.1 + '@codemirror/view': 6.43.7 '@lezer/common': 1.5.2 '@codemirror/lang-css@6.3.1': @@ -3905,7 +4037,7 @@ snapshots: '@codemirror/lang-javascript': 6.2.5 '@codemirror/language': 6.12.4 '@codemirror/state': 6.7.1 - '@codemirror/view': 6.43.6 + '@codemirror/view': 6.43.7 '@lezer/common': 1.5.2 '@lezer/css': 1.3.3 '@lezer/html': 1.3.13 @@ -3916,7 +4048,7 @@ snapshots: '@codemirror/language': 6.12.4 '@codemirror/lint': 6.9.7 '@codemirror/state': 6.7.1 - '@codemirror/view': 6.43.6 + '@codemirror/view': 6.43.7 '@lezer/common': 1.5.2 '@lezer/javascript': 1.5.4 @@ -3929,9 +4061,9 @@ snapshots: dependencies: '@codemirror/autocomplete': 6.20.3 '@codemirror/lang-html': 6.4.11 - '@codemirror/language': 6.12.3 - '@codemirror/state': 6.7.0 - '@codemirror/view': 6.43.2 + '@codemirror/language': 6.12.4 + '@codemirror/state': 6.7.1 + '@codemirror/view': 6.43.7 '@lezer/common': 1.5.2 '@lezer/markdown': 1.6.4 @@ -3953,19 +4085,10 @@ snapshots: '@lezer/lr': 1.4.10 '@lezer/yaml': 1.0.4 - '@codemirror/language@6.12.3': - dependencies: - '@codemirror/state': 6.7.0 - '@codemirror/view': 6.43.2 - '@lezer/common': 1.5.2 - '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.10 - style-mod: 4.1.3 - '@codemirror/language@6.12.4': dependencies: - '@codemirror/state': 6.7.0 - '@codemirror/view': 6.43.2 + '@codemirror/state': 6.7.1 + '@codemirror/view': 6.43.7 '@lezer/common': 1.5.2 '@lezer/highlight': 1.2.3 '@lezer/lr': 1.4.10 @@ -3978,19 +4101,15 @@ snapshots: '@codemirror/lint@6.9.7': dependencies: '@codemirror/state': 6.7.1 - '@codemirror/view': 6.43.6 + '@codemirror/view': 6.43.7 crelt: 1.0.6 '@codemirror/search@6.7.1': dependencies: '@codemirror/state': 6.7.1 - '@codemirror/view': 6.43.6 + '@codemirror/view': 6.43.7 crelt: 1.0.6 - '@codemirror/state@6.7.0': - dependencies: - '@marijn/find-cluster-break': 1.0.2 - '@codemirror/state@6.7.1': dependencies: '@marijn/find-cluster-break': 1.0.2 @@ -3999,19 +4118,12 @@ snapshots: dependencies: '@codemirror/language': 6.12.4 '@codemirror/state': 6.7.1 - '@codemirror/view': 6.43.6 + '@codemirror/view': 6.43.7 '@lezer/highlight': 1.2.3 - '@codemirror/view@6.43.2': - dependencies: - '@codemirror/state': 6.7.0 - crelt: 1.0.6 - style-mod: 4.1.3 - w3c-keyname: 2.2.8 - - '@codemirror/view@6.43.6': + '@codemirror/view@6.43.7': dependencies: - '@codemirror/state': 6.7.0 + '@codemirror/state': 6.7.1 crelt: 1.0.6 style-mod: 4.1.3 w3c-keyname: 2.2.8 @@ -4050,9 +4162,9 @@ snapshots: tslib: 2.8.1 optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))': + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))': dependencies: - eslint: 9.39.4(jiti@2.7.0)(supports-color@7.2.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} @@ -4073,7 +4185,7 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/eslintrc@3.3.5(supports-color@7.2.0)': + '@eslint/eslintrc@3.3.6(supports-color@7.2.0)': dependencies: ajv: 6.15.0 debug: 4.4.3(supports-color@7.2.0) @@ -4081,13 +4193,13 @@ snapshots: globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.1 - js-yaml: 4.2.0 + js-yaml: 4.3.0 minimatch: 3.1.5 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color - '@eslint/js@9.39.4': {} + '@eslint/js@9.39.5': {} '@eslint/object-schema@2.1.7': {} @@ -4585,12 +4697,12 @@ snapshots: react-aria: 3.48.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) react-dom: 19.2.8(react@19.2.8) - '@react-three/drei@10.7.7(@react-three/fiber@9.6.1(@types/react@19.2.14)(immer@11.1.15)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(three@0.185.1))(@types/react@19.2.14)(@types/three@0.184.1)(immer@11.1.15)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(three@0.185.1)': + '@react-three/drei@10.7.7(@react-three/fiber@9.7.0(@types/react@19.2.14)(immer@11.1.15)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(three@0.185.1))(@types/react@19.2.14)(@types/three@0.184.1)(immer@11.1.15)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(three@0.185.1)': dependencies: '@babel/runtime': 7.29.2 '@mediapipe/tasks-vision': 0.10.17 '@monogrid/gainmap-js': 3.4.0(three@0.185.1) - '@react-three/fiber': 9.6.1(@types/react@19.2.14)(immer@11.1.15)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(three@0.185.1) + '@react-three/fiber': 9.7.0(@types/react@19.2.14)(immer@11.1.15)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(three@0.185.1) '@use-gesture/react': 10.3.1(react@19.2.8) camera-controls: 3.1.2(three@0.185.1) cross-env: 7.0.3 @@ -4618,7 +4730,7 @@ snapshots: - '@types/three' - immer - '@react-three/fiber@9.6.1(@types/react@19.2.14)(immer@11.1.15)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(three@0.185.1)': + '@react-three/fiber@9.7.0(@types/react@19.2.14)(immer@11.1.15)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(three@0.185.1)': dependencies: '@babel/runtime': 7.29.2 '@types/webxr': 0.5.24 @@ -4890,40 +5002,40 @@ snapshots: '@types/webxr@0.5.24': {} - '@typescript-eslint/eslint-plugin@8.59.2(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.59.2(@typescript-eslint/parser@8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2))(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) + '@typescript-eslint/parser': 8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2) '@typescript-eslint/scope-manager': 8.59.2 - '@typescript-eslint/type-utils': 8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) - '@typescript-eslint/utils': 8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) + '@typescript-eslint/type-utils': 8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2) + '@typescript-eslint/utils': 8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2) '@typescript-eslint/visitor-keys': 8.59.2 - eslint: 9.39.4(jiti@2.7.0)(supports-color@7.2.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.5.0(typescript@6.0.3) - typescript: 6.0.3 + ts-api-utils: 2.5.0(typescript@7.0.2) + typescript: 7.0.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3)': + '@typescript-eslint/parser@8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2)': dependencies: '@typescript-eslint/scope-manager': 8.59.2 '@typescript-eslint/types': 8.59.2 - '@typescript-eslint/typescript-estree': 8.59.2(supports-color@7.2.0)(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.59.2(supports-color@7.2.0)(typescript@7.0.2) '@typescript-eslint/visitor-keys': 8.59.2 debug: 4.4.3(supports-color@7.2.0) - eslint: 9.39.4(jiti@2.7.0)(supports-color@7.2.0) - typescript: 6.0.3 + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) + typescript: 7.0.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.59.2(supports-color@7.2.0)(typescript@6.0.3)': + '@typescript-eslint/project-service@8.59.2(supports-color@7.2.0)(typescript@7.0.2)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.59.2(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.59.2(typescript@7.0.2) '@typescript-eslint/types': 8.59.2 debug: 4.4.3(supports-color@7.2.0) - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - supports-color @@ -4932,47 +5044,47 @@ snapshots: '@typescript-eslint/types': 8.59.2 '@typescript-eslint/visitor-keys': 8.59.2 - '@typescript-eslint/tsconfig-utils@8.59.2(typescript@6.0.3)': + '@typescript-eslint/tsconfig-utils@8.59.2(typescript@7.0.2)': dependencies: - typescript: 6.0.3 + typescript: 7.0.2 - '@typescript-eslint/type-utils@8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2)': dependencies: '@typescript-eslint/types': 8.59.2 - '@typescript-eslint/typescript-estree': 8.59.2(supports-color@7.2.0)(typescript@6.0.3) - '@typescript-eslint/utils': 8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.59.2(supports-color@7.2.0)(typescript@7.0.2) + '@typescript-eslint/utils': 8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2) debug: 4.4.3(supports-color@7.2.0) - eslint: 9.39.4(jiti@2.7.0)(supports-color@7.2.0) - ts-api-utils: 2.5.0(typescript@6.0.3) - typescript: 6.0.3 + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) + ts-api-utils: 2.5.0(typescript@7.0.2) + typescript: 7.0.2 transitivePeerDependencies: - supports-color '@typescript-eslint/types@8.59.2': {} - '@typescript-eslint/typescript-estree@8.59.2(supports-color@7.2.0)(typescript@6.0.3)': + '@typescript-eslint/typescript-estree@8.59.2(supports-color@7.2.0)(typescript@7.0.2)': dependencies: - '@typescript-eslint/project-service': 8.59.2(supports-color@7.2.0)(typescript@6.0.3) - '@typescript-eslint/tsconfig-utils': 8.59.2(typescript@6.0.3) + '@typescript-eslint/project-service': 8.59.2(supports-color@7.2.0)(typescript@7.0.2) + '@typescript-eslint/tsconfig-utils': 8.59.2(typescript@7.0.2) '@typescript-eslint/types': 8.59.2 '@typescript-eslint/visitor-keys': 8.59.2 debug: 4.4.3(supports-color@7.2.0) minimatch: 10.2.5 semver: 7.7.4 tinyglobby: 0.2.16 - ts-api-utils: 2.5.0(typescript@6.0.3) - typescript: 6.0.3 + ts-api-utils: 2.5.0(typescript@7.0.2) + typescript: 7.0.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3)': + '@typescript-eslint/utils@8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0)) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)) '@typescript-eslint/scope-manager': 8.59.2 '@typescript-eslint/types': 8.59.2 - '@typescript-eslint/typescript-estree': 8.59.2(supports-color@7.2.0)(typescript@6.0.3) - eslint: 9.39.4(jiti@2.7.0)(supports-color@7.2.0) - typescript: 6.0.3 + '@typescript-eslint/typescript-estree': 8.59.2(supports-color@7.2.0)(typescript@7.0.2) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) + typescript: 7.0.2 transitivePeerDependencies: - supports-color @@ -4981,7 +5093,71 @@ snapshots: '@typescript-eslint/types': 8.59.2 eslint-visitor-keys: 5.0.1 - '@uiw/codemirror-extensions-basic-setup@4.25.11(@codemirror/autocomplete@6.20.3)(@codemirror/commands@6.10.3)(@codemirror/language@6.12.4)(@codemirror/lint@6.9.7)(@codemirror/search@6.7.1)(@codemirror/state@6.7.1)(@codemirror/view@6.43.6)': + '@typescript/typescript-aix-ppc64@7.0.2': + optional: true + + '@typescript/typescript-darwin-arm64@7.0.2': + optional: true + + '@typescript/typescript-darwin-x64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-x64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm@7.0.2': + optional: true + + '@typescript/typescript-linux-loong64@7.0.2': + optional: true + + '@typescript/typescript-linux-mips64el@7.0.2': + optional: true + + '@typescript/typescript-linux-ppc64@7.0.2': + optional: true + + '@typescript/typescript-linux-riscv64@7.0.2': + optional: true + + '@typescript/typescript-linux-s390x@7.0.2': + optional: true + + '@typescript/typescript-linux-x64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-sunos-x64@7.0.2': + optional: true + + '@typescript/typescript-win32-arm64@7.0.2': + optional: true + + '@typescript/typescript-win32-x64@7.0.2': + optional: true + + '@typescript/typescript6@6.0.2': + dependencies: + '@typescript/old': typescript@6.0.3 + + '@uiw/codemirror-extensions-basic-setup@4.25.11(@codemirror/autocomplete@6.20.3)(@codemirror/commands@6.10.3)(@codemirror/language@6.12.4)(@codemirror/lint@6.9.7)(@codemirror/search@6.7.1)(@codemirror/state@6.7.1)(@codemirror/view@6.43.7)': dependencies: '@codemirror/autocomplete': 6.20.3 '@codemirror/commands': 6.10.3 @@ -4989,16 +5165,16 @@ snapshots: '@codemirror/lint': 6.9.7 '@codemirror/search': 6.7.1 '@codemirror/state': 6.7.1 - '@codemirror/view': 6.43.6 + '@codemirror/view': 6.43.7 - '@uiw/react-codemirror@4.25.11(@babel/runtime@7.29.2)(@codemirror/autocomplete@6.20.3)(@codemirror/language@6.12.4)(@codemirror/lint@6.9.7)(@codemirror/search@6.7.1)(@codemirror/state@6.7.1)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.43.6)(codemirror@6.0.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + '@uiw/react-codemirror@4.25.11(@babel/runtime@7.29.2)(@codemirror/autocomplete@6.20.3)(@codemirror/language@6.12.4)(@codemirror/lint@6.9.7)(@codemirror/search@6.7.1)(@codemirror/state@6.7.1)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.43.7)(codemirror@6.0.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@babel/runtime': 7.29.2 '@codemirror/commands': 6.10.3 '@codemirror/state': 6.7.1 '@codemirror/theme-one-dark': 6.1.3 - '@codemirror/view': 6.43.6 - '@uiw/codemirror-extensions-basic-setup': 4.25.11(@codemirror/autocomplete@6.20.3)(@codemirror/commands@6.10.3)(@codemirror/language@6.12.4)(@codemirror/lint@6.9.7)(@codemirror/search@6.7.1)(@codemirror/state@6.7.1)(@codemirror/view@6.43.6) + '@codemirror/view': 6.43.7 + '@uiw/codemirror-extensions-basic-setup': 4.25.11(@codemirror/autocomplete@6.20.3)(@codemirror/commands@6.10.3)(@codemirror/language@6.12.4)(@codemirror/lint@6.9.7)(@codemirror/search@6.7.1)(@codemirror/state@6.7.1)(@codemirror/view@6.43.7) codemirror: 6.0.2 react: 19.2.8 react-dom: 19.2.8(react@19.2.8) @@ -5208,10 +5384,10 @@ snapshots: axe-core@4.11.4: {} - axios@1.18.1(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0): + axios@1.19.0(debug@4.4.3(supports-color@7.2.0))(supports-color@7.2.0): dependencies: follow-redirects: 1.16.0(debug@4.4.3(supports-color@7.2.0)) - form-data: 4.0.5 + form-data: 4.0.6 https-proxy-agent: 5.0.1(supports-color@7.2.0) proxy-from-env: 2.1.0 transitivePeerDependencies: @@ -5326,7 +5502,7 @@ snapshots: '@codemirror/lint': 6.9.7 '@codemirror/search': 6.7.1 '@codemirror/state': 6.7.1 - '@codemirror/view': 6.43.6 + '@codemirror/view': 6.43.7 color-convert@1.9.3: dependencies: @@ -5634,29 +5810,29 @@ snapshots: escape-string-regexp@5.0.0: {} - eslint-config-next@16.2.12(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3): + eslint-config-next@16.2.12(@typescript-eslint/parser@8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2))(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2): dependencies: '@next/eslint-plugin-next': 16.2.12 - eslint: 9.39.4(jiti@2.7.0)(supports-color@7.2.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) eslint-import-resolver-node: 0.3.10(supports-color@7.2.0) - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0)) - eslint-plugin-react: 7.37.5(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0)) - eslint-plugin-react-hooks: 7.1.1(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)) + eslint-plugin-react: 7.37.5(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)) + eslint-plugin-react-hooks: 7.1.1(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) globals: 16.4.0 - typescript-eslint: 8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) + typescript-eslint: 8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2) optionalDependencies: - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-webpack - eslint-plugin-import-x - supports-color - eslint-config-prettier@10.1.8(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0)): + eslint-config-prettier@10.1.8(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)): dependencies: - eslint: 9.39.4(jiti@2.7.0)(supports-color@7.2.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) eslint-import-resolver-node@0.3.10(supports-color@7.2.0): dependencies: @@ -5666,33 +5842,33 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.3(supports-color@7.2.0) - eslint: 9.39.4(jiti@2.7.0)(supports-color@7.2.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) get-tsconfig: 4.14.0 is-bun-module: 2.0.0 stable-hash: 0.0.5 tinyglobby: 0.2.16 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@7.2.0))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2))(eslint-import-resolver-node@0.3.10(supports-color@7.2.0))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0): dependencies: debug: 3.2.7(supports-color@7.2.0) optionalDependencies: - '@typescript-eslint/parser': 8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) - eslint: 9.39.4(jiti@2.7.0)(supports-color@7.2.0) + '@typescript-eslint/parser': 8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) eslint-import-resolver-node: 0.3.10(supports-color@7.2.0) - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -5701,9 +5877,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7(supports-color@7.2.0) doctrine: 2.1.0 - eslint: 9.39.4(jiti@2.7.0)(supports-color@7.2.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) eslint-import-resolver-node: 0.3.10(supports-color@7.2.0) - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@7.2.0))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2))(eslint-import-resolver-node@0.3.10(supports-color@7.2.0))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) hasown: 2.0.3 is-core-module: 2.16.2 is-glob: 4.0.3 @@ -5715,13 +5891,13 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) + '@typescript-eslint/parser': 8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0)): + eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)): dependencies: aria-query: 5.3.2 array-includes: 3.1.9 @@ -5731,7 +5907,7 @@ snapshots: axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 9.39.4(jiti@2.7.0)(supports-color@7.2.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) hasown: 2.0.3 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -5740,18 +5916,18 @@ snapshots: safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 - eslint-plugin-react-hooks@7.1.1(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0): + eslint-plugin-react-hooks@7.1.1(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0): dependencies: '@babel/core': 7.29.0(supports-color@7.2.0) '@babel/parser': 7.29.3 - eslint: 9.39.4(jiti@2.7.0)(supports-color@7.2.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) hermes-parser: 0.25.1 zod: 4.4.3 zod-validation-error: 4.0.2(zod@4.4.3) transitivePeerDependencies: - supports-color - eslint-plugin-react@7.37.5(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0)): + eslint-plugin-react@7.37.5(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)): dependencies: array-includes: 3.1.9 array.prototype.findlast: 1.2.5 @@ -5759,7 +5935,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.3.2 - eslint: 9.39.4(jiti@2.7.0)(supports-color@7.2.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) estraverse: 5.3.0 hasown: 2.0.3 jsx-ast-utils: 3.3.5 @@ -5784,15 +5960,15 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0): + eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0)) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.21.2(supports-color@7.2.0) '@eslint/config-helpers': 0.4.2 '@eslint/core': 0.17.0 - '@eslint/eslintrc': 3.3.5(supports-color@7.2.0) - '@eslint/js': 9.39.4 + '@eslint/eslintrc': 3.3.6(supports-color@7.2.0) + '@eslint/js': 9.39.5 '@eslint/plugin-kit': 0.4.1 '@humanfs/node': 0.16.8 '@humanwhocodes/module-importer': 1.0.1 @@ -5903,12 +6079,12 @@ snapshots: dependencies: is-callable: 1.2.7 - form-data@4.0.5: + form-data@4.0.6: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 es-set-tostringtag: 2.1.0 - hasown: 2.0.3 + hasown: 2.0.4 mime-types: 2.1.35 function-bind@1.1.2: {} @@ -6005,6 +6181,10 @@ snapshots: dependencies: function-bind: 1.1.2 + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + hast-util-to-jsx-runtime@2.3.6(supports-color@7.2.0): dependencies: '@types/estree': 1.0.9 @@ -6246,11 +6426,11 @@ snapshots: js-tokens@4.0.0: {} - js-yaml@4.2.0: + js-yaml@4.3.0: dependencies: argparse: 2.0.1 - js-yaml@5.2.2: + js-yaml@5.2.3: dependencies: argparse: 2.0.1 @@ -6373,7 +6553,7 @@ snapshots: dependencies: yallist: 3.1.1 - lucide-react@1.27.0(react@19.2.8): + lucide-react@1.28.0(react@19.2.8): dependencies: react: 19.2.8 @@ -7544,9 +7724,9 @@ snapshots: trough@2.2.0: {} - ts-api-utils@2.5.0(typescript@6.0.3): + ts-api-utils@2.5.0(typescript@7.0.2): dependencies: - typescript: 6.0.3 + typescript: 7.0.2 tsconfig-paths@3.15.0: dependencies: @@ -7604,19 +7784,42 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3): + typescript-eslint@8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.59.2(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) - '@typescript-eslint/parser': 8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) - '@typescript-eslint/typescript-estree': 8.59.2(supports-color@7.2.0)(typescript@6.0.3) - '@typescript-eslint/utils': 8.59.2(eslint@9.39.4(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) - eslint: 9.39.4(jiti@2.7.0)(supports-color@7.2.0) - typescript: 6.0.3 + '@typescript-eslint/eslint-plugin': 8.59.2(@typescript-eslint/parser@8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2))(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2) + '@typescript-eslint/parser': 8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2) + '@typescript-eslint/typescript-estree': 8.59.2(supports-color@7.2.0)(typescript@7.0.2) + '@typescript-eslint/utils': 8.59.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@7.0.2) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) + typescript: 7.0.2 transitivePeerDependencies: - supports-color typescript@6.0.3: {} + typescript@7.0.2: + optionalDependencies: + '@typescript/typescript-aix-ppc64': 7.0.2 + '@typescript/typescript-darwin-arm64': 7.0.2 + '@typescript/typescript-darwin-x64': 7.0.2 + '@typescript/typescript-freebsd-arm64': 7.0.2 + '@typescript/typescript-freebsd-x64': 7.0.2 + '@typescript/typescript-linux-arm': 7.0.2 + '@typescript/typescript-linux-arm64': 7.0.2 + '@typescript/typescript-linux-loong64': 7.0.2 + '@typescript/typescript-linux-mips64el': 7.0.2 + '@typescript/typescript-linux-ppc64': 7.0.2 + '@typescript/typescript-linux-riscv64': 7.0.2 + '@typescript/typescript-linux-s390x': 7.0.2 + '@typescript/typescript-linux-x64': 7.0.2 + '@typescript/typescript-netbsd-arm64': 7.0.2 + '@typescript/typescript-netbsd-x64': 7.0.2 + '@typescript/typescript-openbsd-arm64': 7.0.2 + '@typescript/typescript-openbsd-x64': 7.0.2 + '@typescript/typescript-sunos-x64': 7.0.2 + '@typescript/typescript-win32-arm64': 7.0.2 + '@typescript/typescript-win32-x64': 7.0.2 + unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 diff --git a/frontendv2/pnpm-workspace.yaml b/frontendv2/pnpm-workspace.yaml index 609143a9f..dbb5c3480 100644 --- a/frontendv2/pnpm-workspace.yaml +++ b/frontendv2/pnpm-workspace.yaml @@ -1,6 +1,10 @@ allowBuilds: sharp: true unrs-resolver: true +overrides: + '@codemirror/state': 6.7.1 + '@codemirror/view': 6.43.7 + '@codemirror/language': 6.12.4 minimumReleaseAgeExclude: - prettier@3.8.4 || 3.9.6 - react-qr-code@2.2.0 @@ -8,6 +12,8 @@ minimumReleaseAgeExclude: - react-dom@19.2.8 - react@19.2.8 - recharts@3.10.0 + - typescript@7.0.2 + - '@typescript/typescript6@6.0.2' - '@next/eslint-plugin-next@16.2.11 || 16.2.12' - eslint-config-next@16.2.11 || 16.2.12 - '@next/env@16.2.11 || 16.2.12' @@ -39,7 +45,8 @@ minimumReleaseAgeExclude: - '@radix-ui/react-use-is-hydrated@0.1.2' - '@radix-ui/react-use-layout-effect@1.1.3' - '@radix-ui/react-use-size@1.1.3' - - js-yaml@5.2.2 + - js-yaml@5.2.2 || 5.2.3 + - '@react-three/fiber@9.7.0' onlyBuiltDependencies: - '@scarf/scarf' - '@tree-sitter-grammars/tree-sitter-yaml' diff --git a/frontendv2/scripts/eslint-ts6-shim.cjs b/frontendv2/scripts/eslint-ts6-shim.cjs new file mode 100644 index 000000000..640178e14 --- /dev/null +++ b/frontendv2/scripts/eslint-ts6-shim.cjs @@ -0,0 +1,37 @@ +/* +This file is part of FeatherPanel. + +Copyright (C) 2025 MythicalSystems Studios +Copyright (C) 2025 FeatherPanel Contributors +Copyright (C) 2025 Cassian Gherman (aka NaysKutzu) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +See the LICENSE file or . +*/ + +/** + * TypeScript 7 has no programmatic compiler API yet (lands in 7.1). + * typescript-eslint still imports `typescript` for AST/program APIs. + * Remap those requires to `@typescript/typescript6` for the ESLint process only. + * + * @see https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/#running-side-by-side-with-typescript-6.0 + */ +const Module = require('node:module'); +const path = require('node:path'); + +const ts6Root = path.dirname(require.resolve('@typescript/typescript6/package.json')); +const originalResolveFilename = Module._resolveFilename; + +Module._resolveFilename = function resolveFilename(request, parent, isMain, options) { + if (request === 'typescript' || request.startsWith('typescript/')) { + const suffix = request === 'typescript' ? '' : request.slice('typescript'.length); + const remapped = path.join(ts6Root, suffix || '.'); + return originalResolveFilename.call(this, remapped, parent, isMain, options); + } + + return originalResolveFilename.call(this, request, parent, isMain, options); +}; diff --git a/frontendv2/src/app/(app)/server/[uuidShort]/files/components/dialogs/ImagePreviewDialog.tsx b/frontendv2/src/app/(app)/server/[uuidShort]/files/components/dialogs/ImagePreviewDialog.tsx index 3a040762b..76839c5da 100644 --- a/frontendv2/src/app/(app)/server/[uuidShort]/files/components/dialogs/ImagePreviewDialog.tsx +++ b/frontendv2/src/app/(app)/server/[uuidShort]/files/components/dialogs/ImagePreviewDialog.tsx @@ -19,7 +19,7 @@ import { Button } from '@/components/featherui/Button'; import { Download, X, Loader2, AlertCircle } from 'lucide-react'; import { FileObject } from '@/types/server'; import { formatFileSize } from '@/lib/utils'; -import api from '@/lib/api'; +import { filesApi } from '@/lib/files-api'; import { useTranslation } from '@/contexts/TranslationContext'; interface ImagePreviewDialogProps { @@ -58,14 +58,13 @@ export function ImagePreviewDialog({ setError(null); try { const filePath = currentDirectory === '/' ? file.name : `${currentDirectory}/${file.name}`; - const response = await api.get( - `/user/servers/${uuid}/download-file?path=${encodeURIComponent(filePath)}`, - { - responseType: 'blob', - }, - ); - - const url = URL.createObjectURL(response.data); + const downloadUrl = await filesApi.getDownloadUrl(uuid, filePath); + const response = await fetch(downloadUrl); + if (!response.ok) { + throw new Error(`Download failed with status ${response.status}`); + } + const blob = await response.blob(); + const url = URL.createObjectURL(blob); setBlobUrl(url); } catch (err) { console.error('Failed to fetch image:', err); diff --git a/frontendv2/src/app/(app)/server/[uuidShort]/files/page.tsx b/frontendv2/src/app/(app)/server/[uuidShort]/files/page.tsx index 2bcbf865f..cafc3bd19 100644 --- a/frontendv2/src/app/(app)/server/[uuidShort]/files/page.tsx +++ b/frontendv2/src/app/(app)/server/[uuidShort]/files/page.tsx @@ -699,8 +699,8 @@ export default function ServerFilesPage({ params }: { params: Promise<{ uuidShor ? `${currentDirectory || '/'}${filename}` : `${currentDirectory || '/'}/${filename}`; - const url = `/api/user/servers/${uuidShort}/download-file?path=${encodeURIComponent(path)}`; - window.open(url, '_blank'); + const downloadUrl = await filesApi.getDownloadUrl(uuidShort, path); + window.open(downloadUrl, '_blank'); setActionFile(null); } catch { toast.error(t('files.messages.failed_download')); diff --git a/frontendv2/src/components/Sidebar.tsx b/frontendv2/src/components/Sidebar.tsx index ae30fb8e6..f34cb2b71 100644 --- a/frontendv2/src/components/Sidebar.tsx +++ b/frontendv2/src/components/Sidebar.tsx @@ -29,7 +29,7 @@ import axios from 'axios'; import { useSettings } from '@/contexts/SettingsContext'; import { useSession } from '@/contexts/SessionContext'; import { useTheme } from '@/contexts/ThemeContext'; -import { cn } from '@/lib/utils'; +import { cn, isEnabled } from '@/lib/utils'; import { useNavigation } from '@/hooks/useNavigation'; import { useTranslation } from '@/contexts/TranslationContext'; import type { NavigationItem } from '@/types/navigation'; @@ -78,7 +78,13 @@ function SidebarContent({ }: { mobile?: boolean; collapsed: boolean; - settings: { app_name?: string; app_version?: string; app_logo_white?: string; app_logo_dark?: string } | null; + settings: { + app_name?: string; + app_version?: string; + app_logo_white?: string; + app_logo_dark?: string; + ticket_system_enabled?: string; + } | null; pathname: string; router: ReturnType; setMobileOpen: (open: boolean) => void; @@ -94,6 +100,7 @@ function SidebarContent({ const [collapsedSubmenus, setCollapsedSubmenus] = useState([]); const [unreadTicketCount, setUnreadTicketCount] = useState(0); const adminOpenTicketCount = adminTicketStats?.open_count ?? 0; + const ticketsEnabled = isEnabled(settings?.ticket_system_enabled); useEffect(() => { const saved = localStorage.getItem('featherpanel_collapsed_groups'); @@ -116,6 +123,11 @@ function SidebarContent({ }, []); useEffect(() => { + if (!ticketsEnabled) { + setUnreadTicketCount(0); + return; + } + const fetchUnreadTicketCount = async () => { try { const { data } = await axios.get('/api/user/tickets', { @@ -150,7 +162,7 @@ function SidebarContent({ window.removeEventListener('featherpanel:ticket-replied', onTicketReplied); } }; - }, [pathname]); + }, [pathname, ticketsEnabled]); const toggleGroup = (group: string) => { const newCollapsed = collapsedGroups.includes(group) diff --git a/frontendv2/src/lib/files-api.ts b/frontendv2/src/lib/files-api.ts index 44381be4e..bd1fe2531 100644 --- a/frontendv2/src/lib/files-api.ts +++ b/frontendv2/src/lib/files-api.ts @@ -340,8 +340,12 @@ export const filesApi = { await api.post(`/user/servers/${uuid}/wipe-all-files`); }, - getDownloadUrl: (uuid: string, path: string): string => { - return `/api/user/servers/${uuid}/download-file?path=${encodeURIComponent(path)}`; + getDownloadUrl: async (uuid: string, path: string): Promise => { + const res = await api.get>( + `/user/servers/${uuid}/download-file`, + { params: { path } }, + ); + return res.data.data.download_url; }, compressFiles: async ( uuid: string,