From 26721327a428efe615871363ed68c987b33b6106 Mon Sep 17 00:00:00 2001 From: dalthecow Date: Tue, 1 Jul 2025 13:27:49 -0400 Subject: [PATCH 1/2] copy over changes from build pipeline branch --- eslint.config.js | 234 ++-- jest.setup.ts | 1 - package-lock.json | 1142 +++++++++++++++-- package.json | 13 +- src/ui/.env.example | 1 + src/ui/.env.staging | 4 +- src/ui/app/theme.ts | 1 - .../BlockHeader/BlockHeader.component.tsx | 3 +- .../components/CustomLegendLayer/index.tsx | 3 +- .../Combined/components/DottedLines/index.tsx | 3 +- .../components/CustomLegendLayer/index.tsx | 2 +- .../components/DashedSolidLine/index.tsx | 7 +- .../MetricLine/MetricLine.component.tsx | 2 +- .../components/DottedLines/index.tsx | 3 +- .../MetricsSummary.component.tsx | 7 +- .../MetricValue/MetricValue.component.tsx | 3 +- .../components/MetricsSummary/useSummary.ts | 5 +- .../PageHeader/PageHeader.component.tsx | 1 - .../RequestOverTime.component.tsx | 3 +- .../SectionContainer.component.tsx | 3 +- .../TokenLength/TokenLength.component.tsx | 3 +- .../WorkloadDetails.component.tsx | 3 - .../WorkloadMetrics.component.tsx | 3 - src/ui/lib/hooks/useColor.ts | 4 +- .../store/slices/benchmarks/benchmarks.api.ts | 9 +- .../slices/benchmarks/benchmarks.selectors.ts | 6 +- .../lib/store/slices/runInfo/runInfo.api.ts | 2 +- .../workloadDetails/workloadDetails.api.ts | 2 +- src/ui/next.config.ts | 1 + tests/ui/__mocks__/svg.js | 3 +- tests/ui/integration/page.test.tsx | 2 +- tests/ui/unit/mocks/mockBenchmarks.ts | 2 +- tests/ui/unit/utils/interpolation.test.ts | 6 +- tsconfig.json | 3 - tsconfig.test.json | 10 +- 35 files changed, 1180 insertions(+), 320 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index 178aaccb..bdb830d3 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,76 +1,72 @@ // @ts-check import eslint from '@eslint/js'; -import typescriptPlugin from '@typescript-eslint/eslint-plugin'; -import typescriptParser from '@typescript-eslint/parser'; -import { FlatCompat } from '@eslint/eslintrc'; -import reactPlugin from 'eslint-plugin-react'; -import hooksPlugin from 'eslint-plugin-react-hooks'; +import nextPlugin from '@next/eslint-plugin-next'; +import prettierConfig from 'eslint-config-prettier'; +import cypressPlugin from 'eslint-plugin-cypress'; import importPlugin from 'eslint-plugin-import'; import jestPlugin from 'eslint-plugin-jest'; -import noSecretsPlugin from 'eslint-plugin-no-secrets'; import prettierPlugin from 'eslint-plugin-prettier'; -import prettierConfig from 'eslint-config-prettier'; +import reactPlugin from 'eslint-plugin-react'; +import hooksPlugin from 'eslint-plugin-react-hooks'; import globals from 'globals'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import tseslint from 'typescript-eslint'; +// --- SETUP --- +// Recreate __dirname for ES modules const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); -const compat = new FlatCompat({ - baseDirectory: __dirname, - recommendedConfig: eslint.configs.recommended, -}); +// --- EXPORT ESLINT CONFIG --- +export default tseslint.config( + // 1. Global Ignores + { + ignores: ['node_modules/', '.next/', 'dist/', 'coverage/', '.DS_Store'], + }, -export default [ - // Base configuration + // 2. Base Configurations (Applied to all files) eslint.configs.recommended, + prettierConfig, // Disables ESLint rules that conflict with Prettier. IMPORTANT: Must be after other configs. - // Next.js configuration using FlatCompat - ...compat.extends('next/core-web-vitals'), - - // --- Main Configuration --- + // 3. Configuration for App Source Code (Next.js with Type-Aware Linting) { - files: ['src/**/*.{js,jsx,ts,tsx}', 'tests/**/*.{js,jsx,ts,tsx}'], + files: ['src/ui/**/*.{ts,tsx}'], languageOptions: { - parser: typescriptParser, - ecmaVersion: 2024, - sourceType: 'module', + parser: tseslint.parser, + parserOptions: { + project: true, // Enable type-aware linting + tsconfigRootDir: __dirname, + }, globals: { ...globals.browser, - ...globals.node, - ...globals.jest, - }, - parserOptions: { - ecmaFeatures: { - jsx: true, - }, - project: [ - './src/ui/tsconfig.json', - './tsconfig.test.json', - './tsconfig.cypress.json', - ], - tsconfigRootDir: import.meta.dirname, - noWarnOnMultipleProjects: true, + ...globals.node, // Add Node.js globals for `process` etc. }, }, plugins: { - '@typescript-eslint': typescriptPlugin, + '@typescript-eslint': tseslint.plugin, + '@next/next': nextPlugin, + import: importPlugin, react: reactPlugin, 'react-hooks': hooksPlugin, - import: importPlugin, - jest: jestPlugin, - 'no-secrets': noSecretsPlugin, prettier: prettierPlugin, }, rules: { - // Ccustom rules - complexity: ['warn', { max: 8 }], - curly: ['error', 'all'], + // --- Base rules to disable in favor of TS versions --- 'no-unused-vars': 'off', - // TypeScript rules + // --- Recommended rules from plugins --- + ...tseslint.configs.recommendedTypeChecked.rules, + ...nextPlugin.configs.recommended.rules, + ...nextPlugin.configs['core-web-vitals'].rules, + ...reactPlugin.configs.recommended.rules, + ...hooksPlugin.configs.recommended.rules, + + // --- Prettier --- + 'prettier/prettier': 'error', + + // --- Custom Rules & Overrides --- '@typescript-eslint/no-unused-vars': [ 'warn', { @@ -79,103 +75,103 @@ export default [ caughtErrorsIgnorePattern: '^_', }, ], + '@typescript-eslint/no-floating-promises': 'error', + '@typescript-eslint/no-misused-promises': 'error', '@typescript-eslint/no-explicit-any': 'warn', - // Next.js overrides - '@next/next/no-img-element': 'off', // Allow img tags if needed - '@next/next/no-page-custom-font': 'warn', - - // React rules - 'react/react-in-jsx-scope': 'off', // Not needed in Next.js - 'react/prop-types': 'off', // Using TypeScript - 'react-hooks/rules-of-hooks': 'error', - 'react-hooks/exhaustive-deps': 'warn', - - // Import rules - 'import/no-extraneous-dependencies': [ - 'error', - { - devDependencies: [ - '**/*.test.{js,jsx,ts,tsx}', - '**/*.d.ts', - '**/*.interfaces.ts', - '**/*.setup.{js,ts}', - '**/*.config.{js,mjs,ts}', - 'tests/**/*', - 'cypress/**/*', - ], - optionalDependencies: false, - peerDependencies: false, - }, - ], 'import/order': [ 'error', { - groups: [ - ['builtin', 'external'], - ['internal', 'parent', 'sibling', 'index'], - ], - 'newlines-between': 'always-and-inside-groups', - pathGroups: [ - { - pattern: - '@{app,assets,classes,components,hooks,lib,pages,store,tests,types,utils}/**', - group: 'internal', - position: 'before', - }, - { - pattern: '{.,..}/**', - group: 'internal', - position: 'after', - }, - ], - pathGroupsExcludedImportTypes: ['builtin'], + groups: [['builtin', 'external'], 'internal', ['parent', 'sibling', 'index']], + 'newlines-between': 'always', alphabetize: { order: 'asc', caseInsensitive: true }, }, ], - // Security - 'no-secrets/no-secrets': ['error', { additionalRegexes: {}, ignoreContent: [] }], + 'react/react-in-jsx-scope': 'off', + 'react/prop-types': 'off', - // Prettier - 'prettier/prettier': 'error', + '@next/next/no-html-link-for-pages': 'off', + '@next/next/no-img-element': 'off', + + complexity: ['warn', { max: 8 }], }, settings: { - next: { - rootDir: ['src/ui/', 'tests/ui/'], - }, - 'import/resolver': { - typescript: { - project: [ - './src/ui/tsconfig.json', - './tsconfig.test.json', - './tsconfig.cypress.json', - ], - noWarnOnMultipleProjects: true, - }, + react: { version: 'detect' }, + 'import/resolver': { typescript: true, node: true }, + }, + }, + + // 4. Configuration for Jest Test Files (Type-Aware) + { + files: ['tests/ui/**/*.{test,spec}.{ts,tsx}', 'jest.setup.ts'], + languageOptions: { + parser: tseslint.parser, // Explicitly set parser + parserOptions: { + project: './tsconfig.test.json', + tsconfigRootDir: __dirname, }, - react: { - version: 'detect', + globals: { + ...globals.jest, + ...globals.node, // FIX: Add Node.js globals for `global`, etc. }, }, + plugins: { + jest: jestPlugin, + }, + rules: { + ...jestPlugin.configs['flat/recommended'].rules, + '@typescript-eslint/unbound-method': 'off', + }, }, - // Jest-specific rules for test files + // 5. Configuration for Cypress E2E Test Files (Type-Aware) { files: [ - 'tests/**/*.{js,jsx,ts,tsx}', - '**/*.test.{js,jsx,ts,tsx}', - '**/*.spec.{js,jsx,ts,tsx}', + 'tests/ui/cypress/**/*.{cy,e2e}.{ts,tsx}', + 'tests/ui/cypress/support/**/*.ts', ], + languageOptions: { + parser: tseslint.parser, // Explicitly set parser + parserOptions: { + project: './tsconfig.cypress.json', + tsconfigRootDir: __dirname, + }, + // FIX: This is the correct way to get globals from the Cypress plugin's recommended config. + globals: cypressPlugin.configs.recommended.languageOptions.globals, + }, + plugins: { + cypress: cypressPlugin, + }, + // Apply recommended rules and then add our overrides rules: { - 'jest/expect-expect': 'error', - 'jest/no-focused-tests': 'error', - 'jest/no-identical-title': 'error', - 'jest/prefer-to-have-length': 'warn', - 'jest/valid-expect': 'error', + ...cypressPlugin.configs.recommended.rules, + 'jest/expect-expect': 'off', + 'jest/no-standalone-expect': 'off', + '@typescript-eslint/no-floating-promises': 'off', }, }, - // Prettier config (disables conflicting rules) - prettierConfig, -]; + // 6. Configuration for JS/TS config files + { + files: ['**/*.config.{js,mjs,ts}'], + languageOptions: { + globals: { + ...globals.node, + }, + }, + rules: { + '@typescript-eslint/no-var-requires': 'off', + }, + }, + + // 7. Configuration for JS/TS mock files and test helpers + { + files: ['tests/ui/**/__mocks__/**/*.{js,ts}', 'tests/ui/unit/mocks/**/*.ts'], + languageOptions: { + globals: { + ...globals.node, + }, + }, + } +); diff --git a/jest.setup.ts b/jest.setup.ts index eb162bb7..24fe6072 100644 --- a/jest.setup.ts +++ b/jest.setup.ts @@ -11,7 +11,6 @@ jest.mock('next/dynamic', () => ({ const dynamicModule = jest.requireActual('next/dynamic'); const dynamicActualComp = dynamicModule.default; const RequiredComponent = dynamicActualComp(props[0]); - // eslint-disable-next-line no-unused-expressions, @typescript-eslint/no-unused-expressions RequiredComponent.preload ? RequiredComponent.preload() : RequiredComponent.render.preload(); diff --git a/package-lock.json b/package-lock.json index 7bf63e9a..3337307a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,14 +39,13 @@ "@types/react": "^18.0.28", "@types/react-dom": "^18.0.11", "@types/testing-library__jest-dom": "^5.14.9", - "@typescript-eslint/eslint-plugin": "^8.33.1", - "@typescript-eslint/parser": "^8.33.1", "cross-fetch": "^4.1.0", "cypress": "^13.13.3", "eslint": "^9.0.0", "eslint-config-next": "15.3.2", "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-typescript": "^4.4.2", + "eslint-plugin-cypress": "^5.1.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-jest": "^28.11.0", "eslint-plugin-jsx-a11y": "^6.6.1", @@ -62,14 +61,12 @@ "jest-runner-groups": "^2.2.0", "jest-transform-stub": "^2.0.0", "prettier": "^3.5.3", - "typescript": "^5" + "sharp": "^0.32.0", + "typescript": "^5", + "typescript-eslint": "^8.34.0" }, "engines": { "node": ">=22" - }, - "optionalDependencies": { - "@next/swc-linux-x64-gnu": "^15.3.3", - "@next/swc-linux-x64-musl": "^15.3.3" } }, "node_modules/@adobe/css-tools": { @@ -2041,6 +2038,16 @@ "ms": "^2.1.1" } }, + "node_modules/@emnapi/runtime": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz", + "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@emotion/babel-plugin": { "version": "11.13.5", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", @@ -2416,6 +2423,28 @@ "@img/sharp-libvips-darwin-arm64": "1.1.0" } }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.2.tgz", + "integrity": "sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.1.0" + } + }, "node_modules/@img/sharp-libvips-darwin-arm64": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.1.0.tgz", @@ -2432,6 +2461,342 @@ "url": "https://opencollective.com/libvips" } }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.1.0.tgz", + "integrity": "sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.1.0.tgz", + "integrity": "sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.1.0.tgz", + "integrity": "sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.1.0.tgz", + "integrity": "sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.1.0.tgz", + "integrity": "sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.1.0.tgz", + "integrity": "sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.1.0.tgz", + "integrity": "sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.1.0.tgz", + "integrity": "sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.2.tgz", + "integrity": "sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.2.tgz", + "integrity": "sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.2.tgz", + "integrity": "sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.2.tgz", + "integrity": "sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.2.tgz", + "integrity": "sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.2.tgz", + "integrity": "sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.2.tgz", + "integrity": "sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.4.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.2.tgz", + "integrity": "sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.2.tgz", + "integrity": "sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.2.tgz", + "integrity": "sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -3369,38 +3734,6 @@ "node": ">= 10" } }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "15.3.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.3.3.tgz", - "integrity": "sha512-jJ8HRiF3N8Zw6hGlytCj5BiHyG/K+fnTKVDEKvUCyiQ/0r5tgwO7OgaRiOjjRoIx2vwLR+Rz8hQoPrnmFbJdfw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "15.3.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.3.3.tgz", - "integrity": "sha512-HrUcTr4N+RgiiGn3jjeT6Oo208UT/7BuTr7K0mdKRBtTbT4v9zJqCDKO97DUqqoBK1qyzP1RwvrWTvU6EPh/Cw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@next/swc-win32-arm64-msvc": { "version": "15.3.2", "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.3.2.tgz", @@ -4572,17 +4905,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.34.0.tgz", - "integrity": "sha512-QXwAlHlbcAwNlEEMKQS2RCgJsgXrTJdjXT08xEgbPFa2yYQgVjBymxP5DrfrE7X7iodSzd9qBUHUycdyVJTW1w==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.35.1.tgz", + "integrity": "sha512-9XNTlo7P7RJxbVeICaIIIEipqxLKguyh+3UbXuT2XQuFp6d8VOeDEGuz5IiX0dgZo8CiI6aOFLg4e8cF71SFVg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.34.0", - "@typescript-eslint/type-utils": "8.34.0", - "@typescript-eslint/utils": "8.34.0", - "@typescript-eslint/visitor-keys": "8.34.0", + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/type-utils": "8.35.1", + "@typescript-eslint/utils": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -4596,7 +4929,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.34.0", + "@typescript-eslint/parser": "^8.35.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } @@ -4612,16 +4945,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.34.0.tgz", - "integrity": "sha512-vxXJV1hVFx3IXz/oy2sICsJukaBrtDEQSBiV48/YIV5KWjX1dO+bcIr/kCPrW6weKXvsaGKFNlwH0v2eYdRRbA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.35.1.tgz", + "integrity": "sha512-3MyiDfrfLeK06bi/g9DqJxP5pV74LNv4rFTyvGDmT3x2p1yp1lOd+qYZfiRPIOf/oON+WRZR5wxxuF85qOar+w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.34.0", - "@typescript-eslint/types": "8.34.0", - "@typescript-eslint/typescript-estree": "8.34.0", - "@typescript-eslint/visitor-keys": "8.34.0", + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/typescript-estree": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4" }, "engines": { @@ -4637,14 +4970,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.34.0.tgz", - "integrity": "sha512-iEgDALRf970/B2YExmtPMPF54NenZUf4xpL3wsCRx/lgjz6ul/l13R81ozP/ZNuXfnLCS+oPmG7JIxfdNYKELw==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.35.1.tgz", + "integrity": "sha512-VYxn/5LOpVxADAuP3NrnxxHYfzVtQzLKeldIhDhzC8UHaiQvYlXvKuVho1qLduFbJjjy5U5bkGwa3rUGUb1Q6Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.34.0", - "@typescript-eslint/types": "^8.34.0", + "@typescript-eslint/tsconfig-utils": "^8.35.1", + "@typescript-eslint/types": "^8.35.1", "debug": "^4.3.4" }, "engines": { @@ -4659,14 +4992,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.34.0.tgz", - "integrity": "sha512-9Ac0X8WiLykl0aj1oYQNcLZjHgBojT6cW68yAgZ19letYu+Hxd0rE0veI1XznSSst1X5lwnxhPbVdwjDRIomRw==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.35.1.tgz", + "integrity": "sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.34.0", - "@typescript-eslint/visitor-keys": "8.34.0" + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4677,9 +5010,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.34.0.tgz", - "integrity": "sha512-+W9VYHKFIzA5cBeooqQxqNriAP0QeQ7xTiDuIOr71hzgffm3EL2hxwWBIIj4GuofIbKxGNarpKqIq6Q6YrShOA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.35.1.tgz", + "integrity": "sha512-K5/U9VmT9dTHoNowWZpz+/TObS3xqC5h0xAIjXPw+MNcKV9qg6eSatEnmeAwkjHijhACH0/N7bkhKvbt1+DXWQ==", "dev": true, "license": "MIT", "engines": { @@ -4694,14 +5027,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.34.0.tgz", - "integrity": "sha512-n7zSmOcUVhcRYC75W2pnPpbO1iwhJY3NLoHEtbJwJSNlVAZuwqu05zY3f3s2SDWWDSo9FdN5szqc73DCtDObAg==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.35.1.tgz", + "integrity": "sha512-HOrUBlfVRz5W2LIKpXzZoy6VTZzMu2n8q9C2V/cFngIC5U1nStJgv0tMV4sZPzdf4wQm9/ToWUFPMN9Vq9VJQQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.34.0", - "@typescript-eslint/utils": "8.34.0", + "@typescript-eslint/typescript-estree": "8.35.1", + "@typescript-eslint/utils": "8.35.1", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -4718,9 +5051,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.34.0.tgz", - "integrity": "sha512-9V24k/paICYPniajHfJ4cuAWETnt7Ssy+R0Rbcqo5sSFr3QEZ/8TSoUi9XeXVBGXCaLtwTOKSLGcInCAvyZeMA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.35.1.tgz", + "integrity": "sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==", "dev": true, "license": "MIT", "engines": { @@ -4732,16 +5065,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.34.0.tgz", - "integrity": "sha512-rOi4KZxI7E0+BMqG7emPSK1bB4RICCpF7QD3KCLXn9ZvWoESsOMlHyZPAHyG04ujVplPaHbmEvs34m+wjgtVtg==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.35.1.tgz", + "integrity": "sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.34.0", - "@typescript-eslint/tsconfig-utils": "8.34.0", - "@typescript-eslint/types": "8.34.0", - "@typescript-eslint/visitor-keys": "8.34.0", + "@typescript-eslint/project-service": "8.35.1", + "@typescript-eslint/tsconfig-utils": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -4761,9 +5094,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4800,16 +5133,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.34.0.tgz", - "integrity": "sha512-8L4tWatGchV9A1cKbjaavS6mwYwp39jql8xUmIIKJdm+qiaeHy5KMKlBrf30akXAWBzn2SqKsNOtSENWUwg7XQ==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.35.1.tgz", + "integrity": "sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.34.0", - "@typescript-eslint/types": "8.34.0", - "@typescript-eslint/typescript-estree": "8.34.0" + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/typescript-estree": "8.35.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4824,14 +5157,14 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.34.0.tgz", - "integrity": "sha512-qHV7pW7E85A0x6qyrFn+O+q1k1p3tQCsqIZ1KZ5ESLXY57aTvUd3/a4rdPTeXisvhXn2VQG0VSKUqs8KHF2zcA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.35.1.tgz", + "integrity": "sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.34.0", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "8.35.1", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5355,6 +5688,13 @@ "node": ">= 0.4" } }, + "node_modules/b4a": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", + "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -5551,6 +5891,83 @@ "dev": true, "license": "MIT" }, + "node_modules/bare-events": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz", + "integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==", + "dev": true, + "license": "Apache-2.0", + "optional": true + }, + "node_modules/bare-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.1.5.tgz", + "integrity": "sha512-1zccWBMypln0jEE05LzZt+V/8y8AQsQQqxtklqaIyg5nu6OAYFhZxPXinJTSG+kU5qyNmeLgcn9AW7eHiCHVLA==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-events": "^2.5.4", + "bare-path": "^3.0.0", + "bare-stream": "^2.6.4" + }, + "engines": { + "bare": ">=1.16.0" + }, + "peerDependencies": { + "bare-buffer": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + } + } + }, + "node_modules/bare-os": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.1.tgz", + "integrity": "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "bare": ">=1.14.0" + } + }, + "node_modules/bare-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", + "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-os": "^3.0.1" + } + }, + "node_modules/bare-stream": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.5.tgz", + "integrity": "sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "streamx": "^2.21.0" + }, + "peerDependencies": { + "bare-buffer": "*", + "bare-events": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + }, + "bare-events": { + "optional": true + } + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -5582,6 +5999,18 @@ "tweetnacl": "^0.14.3" } }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "node_modules/blob-util": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", @@ -5869,6 +6298,13 @@ "node": ">= 0.8.0" } }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true, + "license": "ISC" + }, "node_modules/ci-info": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.2.0.tgz", @@ -6000,8 +6436,8 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "devOptional": true, "license": "MIT", - "optional": true, "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" @@ -6034,8 +6470,8 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "devOptional": true, "license": "MIT", - "optional": true, "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" @@ -6645,6 +7081,22 @@ "dev": true, "license": "MIT" }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/dedent": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.6.0.tgz", @@ -6660,6 +7112,16 @@ } } }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -6746,8 +7208,8 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "devOptional": true, "license": "Apache-2.0", - "optional": true, "engines": { "node": ">=8" } @@ -7504,6 +7966,19 @@ "ms": "^2.1.1" } }, + "node_modules/eslint-plugin-cypress": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-cypress/-/eslint-plugin-cypress-5.1.0.tgz", + "integrity": "sha512-tdLXm4aq9vX2hTtKJTUFD3gdNseMKqsf8+P6hI4TtOPdz1LU4xvTpQBd1++qPAsPZP2lyYh71B5mvzu2lBr4Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "globals": "^16.2.0" + }, + "peerDependencies": { + "eslint": ">=9" + } + }, "node_modules/eslint-plugin-import": { "version": "2.31.0", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", @@ -7910,6 +8385,16 @@ "node": ">= 0.8.0" } }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true, + "license": "(MIT OR WTFPL)", + "engines": { + "node": ">=6" + } + }, "node_modules/expect": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", @@ -8056,6 +8541,13 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-glob": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", @@ -8324,6 +8816,13 @@ "tslib": "^2.1.0" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true, + "license": "MIT" + }, "node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -8538,6 +9037,13 @@ "assert-plus": "^1.0.0" } }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "dev": true, + "license": "MIT" + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -11321,6 +11827,19 @@ "node": ">=6" } }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -11368,6 +11887,13 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true, + "license": "MIT" + }, "node_modules/mkdirp/node_modules/minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", @@ -11399,6 +11925,13 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/napi-build-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", + "dev": true, + "license": "MIT" + }, "node_modules/napi-postinstall": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.2.4.tgz", @@ -11508,6 +12041,61 @@ "node": ">= 10" } }, + "node_modules/next/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/next/node_modules/sharp": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.2.tgz", + "integrity": "sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.4", + "semver": "^7.7.2" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.2", + "@img/sharp-darwin-x64": "0.34.2", + "@img/sharp-libvips-darwin-arm64": "1.1.0", + "@img/sharp-libvips-darwin-x64": "1.1.0", + "@img/sharp-libvips-linux-arm": "1.1.0", + "@img/sharp-libvips-linux-arm64": "1.1.0", + "@img/sharp-libvips-linux-ppc64": "1.1.0", + "@img/sharp-libvips-linux-s390x": "1.1.0", + "@img/sharp-libvips-linux-x64": "1.1.0", + "@img/sharp-libvips-linuxmusl-arm64": "1.1.0", + "@img/sharp-libvips-linuxmusl-x64": "1.1.0", + "@img/sharp-linux-arm": "0.34.2", + "@img/sharp-linux-arm64": "0.34.2", + "@img/sharp-linux-s390x": "0.34.2", + "@img/sharp-linux-x64": "0.34.2", + "@img/sharp-linuxmusl-arm64": "0.34.2", + "@img/sharp-linuxmusl-x64": "0.34.2", + "@img/sharp-wasm32": "0.34.2", + "@img/sharp-win32-arm64": "0.34.2", + "@img/sharp-win32-ia32": "0.34.2", + "@img/sharp-win32-x64": "0.34.2" + } + }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -11519,6 +12107,39 @@ "tslib": "^2.0.3" } }, + "node_modules/node-abi": { + "version": "3.75.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz", + "integrity": "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "dev": true, + "license": "MIT" + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -12144,6 +12765,63 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/prebuild-install": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^2.0.0", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prebuild-install/node_modules/tar-fs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", + "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/prebuild-install/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -12374,6 +13052,39 @@ ], "license": "MIT" }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", @@ -12467,6 +13178,21 @@ "react-dom": ">=16.6.0" } }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -12953,53 +13679,35 @@ } }, "node_modules/sharp": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.2.tgz", - "integrity": "sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==", + "version": "0.32.6", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", + "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", + "dev": true, "hasInstallScript": true, "license": "Apache-2.0", - "optional": true, "dependencies": { "color": "^4.2.3", - "detect-libc": "^2.0.4", - "semver": "^7.7.2" + "detect-libc": "^2.0.2", + "node-addon-api": "^6.1.0", + "prebuild-install": "^7.1.1", + "semver": "^7.5.4", + "simple-get": "^4.0.1", + "tar-fs": "^3.0.4", + "tunnel-agent": "^0.6.0" }, "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=14.15.0" }, "funding": { "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.34.2", - "@img/sharp-darwin-x64": "0.34.2", - "@img/sharp-libvips-darwin-arm64": "1.1.0", - "@img/sharp-libvips-darwin-x64": "1.1.0", - "@img/sharp-libvips-linux-arm": "1.1.0", - "@img/sharp-libvips-linux-arm64": "1.1.0", - "@img/sharp-libvips-linux-ppc64": "1.1.0", - "@img/sharp-libvips-linux-s390x": "1.1.0", - "@img/sharp-libvips-linux-x64": "1.1.0", - "@img/sharp-libvips-linuxmusl-arm64": "1.1.0", - "@img/sharp-libvips-linuxmusl-x64": "1.1.0", - "@img/sharp-linux-arm": "0.34.2", - "@img/sharp-linux-arm64": "0.34.2", - "@img/sharp-linux-s390x": "0.34.2", - "@img/sharp-linux-x64": "0.34.2", - "@img/sharp-linuxmusl-arm64": "0.34.2", - "@img/sharp-linuxmusl-x64": "0.34.2", - "@img/sharp-wasm32": "0.34.2", - "@img/sharp-win32-arm64": "0.34.2", - "@img/sharp-win32-ia32": "0.34.2", - "@img/sharp-win32-x64": "0.34.2" } }, "node_modules/sharp/node_modules/semver": { "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, "license": "ISC", - "optional": true, "bin": { "semver": "bin/semver.js" }, @@ -13113,12 +13821,59 @@ "dev": true, "license": "ISC" }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "devOptional": true, "license": "MIT", - "optional": true, "dependencies": { "is-arrayish": "^0.3.1" } @@ -13127,8 +13882,8 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "license": "MIT", - "optional": true + "devOptional": true, + "license": "MIT" }, "node_modules/sisteransi": { "version": "1.0.5", @@ -13307,6 +14062,30 @@ "node": ">=10.0.0" } }, + "node_modules/streamx": { + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.1.tgz", + "integrity": "sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -13645,6 +14424,33 @@ "url": "https://opencollective.com/synckit" } }, + "node_modules/tar-fs": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", + "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^4.0.1", + "bare-path": "^3.0.0" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -13660,6 +14466,16 @@ "node": ">=8" } }, + "node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, "node_modules/throttleit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", @@ -14011,6 +14827,29 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.35.1.tgz", + "integrity": "sha512-xslJjFzhOmHYQzSB/QTeASAHbjmxOGEP6Coh93TXmUBFQoJ1VU35UHIDmG06Jd6taf3wqqC1ntBnCMeymy5Ovw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.35.1", + "@typescript-eslint/parser": "8.35.1", + "@typescript-eslint/utils": "8.35.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, "node_modules/unbox-primitive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", @@ -14195,6 +15034,13 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -14583,6 +15429,36 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.3.2.tgz", + "integrity": "sha512-uRBo6THWei0chz+Y5j37qzx+BtoDRFIkDzZjlpCItBRXyMPIg079eIkOCl3aqr2tkxL4HFyJ4GHDes7W8HuAUg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.3.2.tgz", + "integrity": "sha512-+uxFlPuCNx/T9PdMClOqeE8USKzj8tVz37KflT3Kdbx/LOlZBRI2yxuIcmx1mPNK8DwSOMNCr4ureSet7eyC0w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } } } } diff --git a/package.json b/package.json index 958d3491..3abaf7b3 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "scripts": { "dev": "next dev src/ui", "build": "next build src/ui", - "lint": "next lint src/ui", + "lint": "next lint --fix src/ui", "type-check": "tsc -p src/ui/tsconfig.json --noEmit && tsc -p tsconfig.test.json --noEmit && tsc -p tsconfig.cypress.json --noEmit", "format": "prettier --write .", "prepare": "husky", @@ -49,14 +49,13 @@ "@types/react": "^18.0.28", "@types/react-dom": "^18.0.11", "@types/testing-library__jest-dom": "^5.14.9", - "@typescript-eslint/eslint-plugin": "^8.33.1", - "@typescript-eslint/parser": "^8.33.1", "cross-fetch": "^4.1.0", "cypress": "^13.13.3", "eslint": "^9.0.0", "eslint-config-next": "15.3.2", "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-typescript": "^4.4.2", + "eslint-plugin-cypress": "^5.1.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-jest": "^28.11.0", "eslint-plugin-jsx-a11y": "^6.6.1", @@ -72,11 +71,9 @@ "jest-runner-groups": "^2.2.0", "jest-transform-stub": "^2.0.0", "prettier": "^3.5.3", - "typescript": "^5" - }, - "optionalDependencies": { - "@next/swc-linux-x64-gnu": "^15.3.3", - "@next/swc-linux-x64-musl": "^15.3.3" + "sharp": "^0.32.0", + "typescript": "^5", + "typescript-eslint": "^8.34.0" }, "lint-staged": { "*.js": "eslint --cache --fix", diff --git a/src/ui/.env.example b/src/ui/.env.example index 06812a30..44ab168b 100644 --- a/src/ui/.env.example +++ b/src/ui/.env.example @@ -1,3 +1,4 @@ ASSET_PREFIX=http://localhost:3000 BASE_PATH=http://localhost:3000 NEXT_PUBLIC_USE_MOCK_API=true +USE_MOCK_DATA=true diff --git a/src/ui/.env.staging b/src/ui/.env.staging index 20142e5d..66c8d235 100644 --- a/src/ui/.env.staging +++ b/src/ui/.env.staging @@ -1,3 +1,3 @@ -ASSET_PREFIX=https://staging.guidellm.neuralmagic.com -BASE_PATH=/guidellm-ui/staging +ASSET_PREFIX=https://review.neuralmagic.com/guidellm-ui/dev/_next +BASE_PATH=/guidellm-ui/dev NEXT_PUBLIC_USE_MOCK_API=true diff --git a/src/ui/app/theme.ts b/src/ui/app/theme.ts index fac120eb..328388e4 100644 --- a/src/ui/app/theme.ts +++ b/src/ui/app/theme.ts @@ -50,7 +50,6 @@ import { RED_SHADES, OUTER_SPACE_GRAY, } from '../lib/utils/Colors'; - // Spezia import SpeziaMedium from './assets/fonts/spezia/Spezia-Medium.otf'; import SpeziaRegular from './assets/fonts/spezia/Spezia-Regular.otf'; diff --git a/src/ui/lib/components/BlockHeader/BlockHeader.component.tsx b/src/ui/lib/components/BlockHeader/BlockHeader.component.tsx index 8e8587ee..0b53fe46 100644 --- a/src/ui/lib/components/BlockHeader/BlockHeader.component.tsx +++ b/src/ui/lib/components/BlockHeader/BlockHeader.component.tsx @@ -1,9 +1,8 @@ 'use client'; import { Box, Typography, useTheme } from '@mui/material'; -import { Info } from '@assets/icons'; - import { SvgContainer } from '@/lib/utils/SvgContainer'; +import { Info } from '@assets/icons'; import { BlockHeaderProps } from './BlockHeader.interfaces'; import { CustomDivider } from './BlockHeader.styles'; diff --git a/src/ui/lib/components/Charts/Combined/components/CustomLegendLayer/index.tsx b/src/ui/lib/components/Charts/Combined/components/CustomLegendLayer/index.tsx index 3f390695..40214bbd 100644 --- a/src/ui/lib/components/Charts/Combined/components/CustomLegendLayer/index.tsx +++ b/src/ui/lib/components/Charts/Combined/components/CustomLegendLayer/index.tsx @@ -1,8 +1,7 @@ import { useTheme } from '@mui/material'; -import useLineColors from '../../../common/useLineColors'; - import { CustomLegendLayerProps } from './CustomLegendLayer.interfaces'; +import useLineColors from '../../../common/useLineColors'; const LEGEND_HEIGHT = 20; diff --git a/src/ui/lib/components/Charts/Combined/components/DottedLines/index.tsx b/src/ui/lib/components/Charts/Combined/components/DottedLines/index.tsx index b4df2145..c8a76069 100644 --- a/src/ui/lib/components/Charts/Combined/components/DottedLines/index.tsx +++ b/src/ui/lib/components/Charts/Combined/components/DottedLines/index.tsx @@ -1,8 +1,7 @@ import React from 'react'; -import useLineColors from '../../../common/useLineColors'; - import { DottedLinesProps } from './DottedLines.interfaces'; +import useLineColors from '../../../common/useLineColors'; const DottedLines = ({ lines, diff --git a/src/ui/lib/components/Charts/DashedLine/components/CustomLegendLayer/index.tsx b/src/ui/lib/components/Charts/DashedLine/components/CustomLegendLayer/index.tsx index 81bd8c20..bc04c481 100644 --- a/src/ui/lib/components/Charts/DashedLine/components/CustomLegendLayer/index.tsx +++ b/src/ui/lib/components/Charts/DashedLine/components/CustomLegendLayer/index.tsx @@ -39,7 +39,7 @@ export const CustomLegendLayer = ({ series, ...rest }: CustomLegendLayerProps) = y1="0" x2="20" y2="0" - stroke={getColor(item.solid)} + stroke={getColor(Boolean(item.solid))} strokeWidth={2} strokeDasharray={item?.solid ? '' : '4,4'} /> diff --git a/src/ui/lib/components/Charts/DashedLine/components/DashedSolidLine/index.tsx b/src/ui/lib/components/Charts/DashedLine/components/DashedSolidLine/index.tsx index dd786b6a..952ff24a 100644 --- a/src/ui/lib/components/Charts/DashedLine/components/DashedSolidLine/index.tsx +++ b/src/ui/lib/components/Charts/DashedLine/components/DashedSolidLine/index.tsx @@ -1,8 +1,7 @@ import { useTheme } from '@mui/material'; -import { toNumberValue } from '../../helpers'; - import { DashedSolidLineProps } from './DashedSolidLine.interfaces'; +import { toNumberValue } from '../../helpers'; export const DashedSolidLine = ({ series, @@ -48,7 +47,7 @@ export const DashedSolidLine = ({ return linePath !== null ? linePath : undefined; })()} fill="none" - stroke={getColor(solid)} + stroke={getColor(Boolean(solid))} style={ !solid ? { @@ -67,7 +66,7 @@ export const DashedSolidLine = ({ cx={xScale(toNumberValue(d.data.x))} cy={yScale(toNumberValue(d.data.y))} r={4} - fill={getColor(solid)} + fill={getColor(Boolean(solid))} /> ))} diff --git a/src/ui/lib/components/Charts/MetricLine/MetricLine.component.tsx b/src/ui/lib/components/Charts/MetricLine/MetricLine.component.tsx index f99c98f1..06bb386e 100644 --- a/src/ui/lib/components/Charts/MetricLine/MetricLine.component.tsx +++ b/src/ui/lib/components/Charts/MetricLine/MetricLine.component.tsx @@ -2,9 +2,9 @@ import { useTheme } from '@mui/material'; import { ResponsiveLine } from '@nivo/line'; import React, { FC } from 'react'; -import { MetricLineProps } from '.'; import { useColor } from '@/lib/hooks/useColor'; +import { MetricLineProps } from '.'; import CustomAxes from './components/CustomAxes'; import ThresholdBar from './components/ThresholdBar'; import { ScaleType } from '../DashedLine/DashedLine.interfaces'; diff --git a/src/ui/lib/components/Charts/MiniCombined/components/DottedLines/index.tsx b/src/ui/lib/components/Charts/MiniCombined/components/DottedLines/index.tsx index 52b8cbce..7c14fc15 100644 --- a/src/ui/lib/components/Charts/MiniCombined/components/DottedLines/index.tsx +++ b/src/ui/lib/components/Charts/MiniCombined/components/DottedLines/index.tsx @@ -1,6 +1,5 @@ -import useLineColors from '../../../common/useLineColors'; - import { DottedLinesProps } from './DottedLines.interfaces'; +import useLineColors from '../../../common/useLineColors'; const DottedLines = ({ lines, diff --git a/src/ui/lib/components/MetricsSummary/MetricsSummary.component.tsx b/src/ui/lib/components/MetricsSummary/MetricsSummary.component.tsx index ef10d209..ae9a428b 100644 --- a/src/ui/lib/components/MetricsSummary/MetricsSummary.component.tsx +++ b/src/ui/lib/components/MetricsSummary/MetricsSummary.component.tsx @@ -2,6 +2,9 @@ import { Box, Button, Typography, useTheme } from '@mui/material'; import React, { ElementType } from 'react'; import { useDispatch, useSelector } from 'react-redux'; +import { MetricLine, LineColor } from '@/lib/components/Charts/MetricLine'; +import { selectSloState } from '@/lib/store/slices/slo/slo.selectors'; +import { setCurrentRequestRate } from '@/lib/store/slices/slo/slo.slice'; import { Expand } from '@assets/icons'; import { @@ -11,10 +14,6 @@ import { } from '../../store/slices/benchmarks'; import { selectRunInfo } from '../../store/slices/runInfo'; import { formatNumber } from '../../utils/helpers'; -import { MetricLine, LineColor } from '@/lib/components/Charts/MetricLine'; -import { selectSloState } from '@/lib/store/slices/slo/slo.selectors'; -import { setCurrentRequestRate } from '@/lib/store/slices/slo/slo.slice'; - import { BlockHeader } from '../BlockHeader'; import { Input } from '../Input'; import { MetricValue } from './components/MetricValue'; diff --git a/src/ui/lib/components/MetricsSummary/components/MetricValue/MetricValue.component.tsx b/src/ui/lib/components/MetricsSummary/components/MetricValue/MetricValue.component.tsx index 4d524858..1e9daeb4 100644 --- a/src/ui/lib/components/MetricsSummary/components/MetricValue/MetricValue.component.tsx +++ b/src/ui/lib/components/MetricsSummary/components/MetricValue/MetricValue.component.tsx @@ -1,9 +1,8 @@ import { Box, Typography } from '@mui/material'; import { FC } from 'react'; -import { CheckCircle, WarningCircle } from '@assets/icons'; - import { useColor } from '@/lib/hooks/useColor'; +import { CheckCircle, WarningCircle } from '@assets/icons'; import { MetricValueProps } from './MetricValue.interfaces'; diff --git a/src/ui/lib/components/MetricsSummary/useSummary.ts b/src/ui/lib/components/MetricsSummary/useSummary.ts index e9445266..0a6f550c 100644 --- a/src/ui/lib/components/MetricsSummary/useSummary.ts +++ b/src/ui/lib/components/MetricsSummary/useSummary.ts @@ -2,11 +2,12 @@ import { SelectChangeEvent } from '@mui/material'; import { ChangeEvent, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; +import { Point } from '@/lib/components/Charts/common/interfaces'; + import { selectMetricsSummaryLineData } from '../../store/slices/benchmarks'; import { selectSloState } from '../../store/slices/slo/slo.selectors'; import { setEnforcedPercentile, setSloValue } from '../../store/slices/slo/slo.slice'; import { ceil, floor } from '../../utils/helpers'; -import { Point } from '@/lib/components/Charts/common/interfaces'; type Errors = { [key: string]: string | undefined }; @@ -93,7 +94,7 @@ export const useSummary = () => { const handlePercentileChange = (event: SelectChangeEvent) => { // TODO: need to validate slos on percentile change - const newValue = `${event.target.value}`; + const newValue = `${event.target.value as string}`; dispatch(setEnforcedPercentile(newValue)); }; diff --git a/src/ui/lib/components/PageHeader/PageHeader.component.tsx b/src/ui/lib/components/PageHeader/PageHeader.component.tsx index 92fc9bc8..48af2ffc 100644 --- a/src/ui/lib/components/PageHeader/PageHeader.component.tsx +++ b/src/ui/lib/components/PageHeader/PageHeader.component.tsx @@ -8,7 +8,6 @@ import { Open } from '@assets/icons'; import { useGetRunInfoQuery } from '../../store/slices/runInfo'; import { formateDate, getFileSize } from '../../utils/helpers'; import { SvgContainer } from '../../utils/SvgContainer'; - import { SpecBadge } from '../SpecBadge'; import { HeaderCell, HeaderWrapper } from './PageHeader.styles'; diff --git a/src/ui/lib/components/RequestOverTime/RequestOverTime.component.tsx b/src/ui/lib/components/RequestOverTime/RequestOverTime.component.tsx index 3d508960..b0633ba1 100644 --- a/src/ui/lib/components/RequestOverTime/RequestOverTime.component.tsx +++ b/src/ui/lib/components/RequestOverTime/RequestOverTime.component.tsx @@ -1,10 +1,9 @@ import { Box, Grid, Typography } from '@mui/material'; import { FC } from 'react'; +import { RequestOverTimeProps } from './RequestOverTime.interfaces'; import { Badge } from '../../components/Badge'; import { SpecBadge } from '../../components/SpecBadge'; - -import { RequestOverTimeProps } from './RequestOverTime.interfaces'; import { MiniCombined } from '../Charts/MiniCombined'; import ContainerSizeWrapper, { ContainerSize, diff --git a/src/ui/lib/components/SectionContainer/SectionContainer.component.tsx b/src/ui/lib/components/SectionContainer/SectionContainer.component.tsx index cec8a89e..e432112f 100644 --- a/src/ui/lib/components/SectionContainer/SectionContainer.component.tsx +++ b/src/ui/lib/components/SectionContainer/SectionContainer.component.tsx @@ -4,10 +4,9 @@ import { MutableRefObject, useEffect, useRef, useState } from 'react'; import { ArrowDown, ArrowUp } from '@assets/icons'; -import { SvgContainer } from '../../utils/SvgContainer'; - import { SectionContainerProps } from './SectionContainer.interfaces'; import { Container, RoundedButton } from './SectionContainer.styles'; +import { SvgContainer } from '../../utils/SvgContainer'; export const Component = ({ children }: SectionContainerProps) => { const theme = useTheme(); diff --git a/src/ui/lib/components/TokenLength/TokenLength.component.tsx b/src/ui/lib/components/TokenLength/TokenLength.component.tsx index 1b8f6681..aaca273f 100644 --- a/src/ui/lib/components/TokenLength/TokenLength.component.tsx +++ b/src/ui/lib/components/TokenLength/TokenLength.component.tsx @@ -1,13 +1,12 @@ import { Box, Typography } from '@mui/material'; import { FC } from 'react'; +import { TokenLengthProps } from './TokenLength.interfaces'; import { MiniCombined } from '../../components/Charts/MiniCombined'; import ContainerSizeWrapper, { ContainerSize, } from '../../components/Charts/MiniCombined/components/ContainerSizeWrapper'; -import { TokenLengthProps } from './TokenLength.interfaces'; - export const Component: FC = ({ label, tokenCount, bars, lines }) => ( { diff --git a/src/ui/lib/components/WorkloadMetrics/WorkloadMetrics.component.tsx b/src/ui/lib/components/WorkloadMetrics/WorkloadMetrics.component.tsx index 8162dffa..b717bb11 100644 --- a/src/ui/lib/components/WorkloadMetrics/WorkloadMetrics.component.tsx +++ b/src/ui/lib/components/WorkloadMetrics/WorkloadMetrics.component.tsx @@ -13,11 +13,8 @@ import { selectMetricsDetailsLineData, useGetBenchmarksQuery, } from '../../store/slices/benchmarks'; - import { selectSloState } from '../../store/slices/slo/slo.selectors'; - import { formatNumber } from '../../utils/helpers'; - import { BlockHeader } from '../BlockHeader'; import { GraphTitle } from '../GraphTitle'; import { MetricsContainer } from '../MetricsContainer'; diff --git a/src/ui/lib/hooks/useColor.ts b/src/ui/lib/hooks/useColor.ts index bc519bad..28c5df77 100644 --- a/src/ui/lib/hooks/useColor.ts +++ b/src/ui/lib/hooks/useColor.ts @@ -10,9 +10,9 @@ export const useColor = (colorType: LineColor | undefined) => { case LineColor.Secondary: return theme.palette.secondary.main; case LineColor.Tertiary: - return theme.palette.tertiary.main as string; + return theme.palette.tertiary.main; case LineColor.Quarternary: - return theme.palette.quarternary.main as string; + return theme.palette.quarternary.main; default: return theme.palette.surface.onSurfaceAccent; } diff --git a/src/ui/lib/store/slices/benchmarks/benchmarks.api.ts b/src/ui/lib/store/slices/benchmarks/benchmarks.api.ts index f1a7b52e..67d867d7 100644 --- a/src/ui/lib/store/slices/benchmarks/benchmarks.api.ts +++ b/src/ui/lib/store/slices/benchmarks/benchmarks.api.ts @@ -1,16 +1,14 @@ import { ThunkDispatch, UnknownAction } from '@reduxjs/toolkit'; import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; -import { formatNumber } from '../../../utils/helpers'; - import { Benchmarks, MetricData } from './benchmarks.interfaces'; +import { formatNumber } from '../../../utils/helpers'; import { defaultPercentile } from '../slo/slo.constants'; -import { SloState } from '../slo/slo.interfaces'; import { setSloData } from '../slo/slo.slice'; const USE_MOCK_API = process.env.NEXT_PUBLIC_USE_MOCK_API === 'true'; -const fetchBenchmarks = async () => { +const fetchBenchmarks = () => { return { data: window.benchmarks as Benchmarks }; }; @@ -30,7 +28,8 @@ const getAverageValueForPercentile = ( const setDefaultSLOs = ( data: Benchmarks, - dispatch: ThunkDispatch + // eslint-disable-next-line @typescript-eslint/no-explicit-any + dispatch: ThunkDispatch ) => { // temporarily set default slo values, long term the backend should set default slos that will not just be the avg at the default percentile const firstBM = data.benchmarks[0]; diff --git a/src/ui/lib/store/slices/benchmarks/benchmarks.selectors.ts b/src/ui/lib/store/slices/benchmarks/benchmarks.selectors.ts index 4a86d422..9453f772 100644 --- a/src/ui/lib/store/slices/benchmarks/benchmarks.selectors.ts +++ b/src/ui/lib/store/slices/benchmarks/benchmarks.selectors.ts @@ -1,12 +1,12 @@ import { createSelector } from '@reduxjs/toolkit'; +import { Point } from '@/lib/components/Charts/common/interfaces'; + +import { BenchmarkMetrics, PercentileValues } from './benchmarks.interfaces'; import { PercentileItem } from '../../../components/DistributionPercentiles'; import { formatNumber } from '../../../utils/helpers'; import { createMonotoneSpline } from '../../../utils/interpolation'; import { RootState } from '../../index'; -import { Point } from '@/lib/components/Charts/common/interfaces'; - -import { BenchmarkMetrics, PercentileValues } from './benchmarks.interfaces'; import { selectSloState } from '../slo/slo.selectors'; export const selectBenchmarks = (state: RootState) => state.benchmarks.data; diff --git a/src/ui/lib/store/slices/runInfo/runInfo.api.ts b/src/ui/lib/store/slices/runInfo/runInfo.api.ts index 9c510b5b..879ef19f 100644 --- a/src/ui/lib/store/slices/runInfo/runInfo.api.ts +++ b/src/ui/lib/store/slices/runInfo/runInfo.api.ts @@ -4,7 +4,7 @@ import { RunInfo } from './runInfo.interfaces'; const USE_MOCK_API = process.env.NEXT_PUBLIC_USE_MOCK_API === 'true'; -const fetchRunInfo = async () => { +const fetchRunInfo = () => { return { data: window.run_info as RunInfo }; }; diff --git a/src/ui/lib/store/slices/workloadDetails/workloadDetails.api.ts b/src/ui/lib/store/slices/workloadDetails/workloadDetails.api.ts index 6720f865..398b208a 100644 --- a/src/ui/lib/store/slices/workloadDetails/workloadDetails.api.ts +++ b/src/ui/lib/store/slices/workloadDetails/workloadDetails.api.ts @@ -4,7 +4,7 @@ import { WorkloadDetails } from './workloadDetails.interfaces'; const USE_MOCK_API = process.env.NEXT_PUBLIC_USE_MOCK_API === 'true'; -const fetchWorkloadDetails = async () => { +const fetchWorkloadDetails = () => { return { data: window.workload_details as WorkloadDetails }; }; diff --git a/src/ui/next.config.ts b/src/ui/next.config.ts index a9b9d123..557b7e1c 100644 --- a/src/ui/next.config.ts +++ b/src/ui/next.config.ts @@ -3,6 +3,7 @@ import type { NextConfig } from 'next'; const nextConfig: NextConfig = { images: { unoptimized: true }, output: 'export', + assetPrefix: process.env.ASSET_PREFIX || '', webpack(config) { // Grab the existing rule that handles SVG imports const fileLoaderRule = config.module.rules.find((rule: any) => diff --git a/tests/ui/__mocks__/svg.js b/tests/ui/__mocks__/svg.js index 516109b1..9260dc35 100644 --- a/tests/ui/__mocks__/svg.js +++ b/tests/ui/__mocks__/svg.js @@ -1,3 +1,4 @@ -export default 'svg'; +const svgMock = 'svg'; +export default svgMock; export const ReactComponent = 'div'; //This was from svgr docs: https://react-svgr.com/docs/jest/ diff --git a/tests/ui/integration/page.test.tsx b/tests/ui/integration/page.test.tsx index 3e765a94..85c4bee8 100644 --- a/tests/ui/integration/page.test.tsx +++ b/tests/ui/integration/page.test.tsx @@ -2,7 +2,7 @@ import { render, waitFor } from '@testing-library/react'; import Home from '@/app/page'; -import mockBenchmarks from '../unit/mocks/mockBenchmarks'; +import { mockBenchmarks } from '../unit/mocks/mockBenchmarks'; const jsonResponse = (data: unknown, status = 200) => Promise.resolve( diff --git a/tests/ui/unit/mocks/mockBenchmarks.ts b/tests/ui/unit/mocks/mockBenchmarks.ts index 29b9232e..5acd7d12 100644 --- a/tests/ui/unit/mocks/mockBenchmarks.ts +++ b/tests/ui/unit/mocks/mockBenchmarks.ts @@ -1,4 +1,4 @@ -export default [ +export const mockBenchmarks = [ { requestsPerSecond: 0.6668550387660497, tpot: { diff --git a/tests/ui/unit/utils/interpolation.test.ts b/tests/ui/unit/utils/interpolation.test.ts index d0173548..244ec811 100644 --- a/tests/ui/unit/utils/interpolation.test.ts +++ b/tests/ui/unit/utils/interpolation.test.ts @@ -36,10 +36,11 @@ test('no local extremas added', () => { const ys = xs.map((x) => 1 + Math.sin((3 * Math.PI * x) / 10)); // check that each interpolated point is between its two bounding points const interpolate = createMonotoneSpline(xs, ys); + const loopedValuesToTest: { expected: number; actual: number }[] = []; for (let i = xs[0]; i < xs[xs.length - 1]; i += 0.01) { const upperIndex = xs.findIndex((x) => x >= i); if (upperIndex === 0) { - expect(interpolate(i)).toBeCloseTo(ys[0]); + loopedValuesToTest.push({ expected: interpolate(i), actual: ys[0] }); continue; } const lowerY = ys[upperIndex - 1]; @@ -47,4 +48,7 @@ test('no local extremas added', () => { expect(interpolate(i)).toBeLessThanOrEqual(Math.max(lowerY, upperY)); expect(interpolate(i)).toBeGreaterThanOrEqual(Math.min(lowerY, upperY)); } + loopedValuesToTest.forEach((value) => { + expect(value.expected).toBeCloseTo(value.actual); + }); }); diff --git a/tsconfig.json b/tsconfig.json index 222ab61a..bdebc2ee 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,13 +1,10 @@ { "extends": "./tsconfig.base.json", - "compilerOptions": { "types": ["node"], "allowJs": false, "isolatedModules": true }, - "include": ["*.ts", "*.cts", "*.mts", "scripts/**/*", "types/**/*"], - "exclude": ["src/ui", "tests", "node_modules"] } diff --git a/tsconfig.test.json b/tsconfig.test.json index 7d85d6fe..dc1ecd14 100644 --- a/tsconfig.test.json +++ b/tsconfig.test.json @@ -6,7 +6,13 @@ }, "include": [ "jest.setup.ts", - "tests/ui/unit/**/*.{ts,tsx}", - "tests/ui/integration/**/*.{ts,tsx}" + "tests/ui/unit/**/*.ts", + "tests/ui/unit/**/*.tsx", + "tests/ui/integration/**/*.ts", + "tests/ui/integration/**/*.tsx", + "tests/ui/test.helper.tsx", + "tests/ui/__mocks__", + "src/ui/app/types", + "src/ui/types" ] } From c2eb830b54fa2e430ff3daf635fbb4594d4c29ef Mon Sep 17 00:00:00 2001 From: dalthecow Date: Tue, 1 Jul 2025 17:32:43 -0400 Subject: [PATCH 2/2] update readme to remove stuff that isn't landed yet --- README.md | 36 +----------------------------------- 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/README.md b/README.md index 1e489bb5..5355430a 100644 --- a/README.md +++ b/README.md @@ -159,41 +159,7 @@ GuideLLM UI is a companion frontend for visualizing the results of a GuideLLM be ### 🛠 Running the UI -1. Use the Hosted Build (Recommended for Most Users) - -After running a benchmark with GuideLLM, a report.html file will be generated (by default at guidellm_report/report.html). This file references the latest stable version of the UI hosted at: - -``` -https://neuralmagic.github.io/guidellm/ui/dev/ -``` - -Open the file in your browser and you're done—no setup required. - -2. Build and Serve the UI Locally (For Development) This option is useful if: - -- You are actively developing the UI - -- You want to test changes to the UI before publishing - -- You want full control over how the report is displayed - -```bash -npm install -npm run build -npx serve out -``` - -This will start a local server (e.g., at http://localhost:3000). Then, in your GuideLLM config or CLI flags, point to this local server as the asset base for report generation. - -### 🧪 Development Notes - -During UI development, it can be helpful to view sample data. We include a sample benchmark run wired into the Redux store under: - -``` -src/lib/store/[runInfo/workloadDetails/benchmarks]WindowData.ts -``` - -In the future this will be replaced by a configurable untracked file for dev use. +The UI is a WIP, check more recent PRs for the latest updates ## Resources