litellm/ui/litellm-dashboard/vitest.config.ts
ryan-crabbe-berri 2e8403a073
fix(ui): bundle provider logos as static imports and unify fallback in Logo component (#34125)
* fix(ui): bundle provider logos as static imports and unify fallback in Logo component

providerLogoMap values are now content-hashed bundle URLs emitted by
static imports instead of /ui/assets/logos/ path strings, so any
deployment that serves the app JS also serves the logos: dev server,
proxy /ui mount, server_root_path sub-paths, and the split-chart nginx
image where the old route 404d in production. A missing file is now a
build error instead of a silent runtime 404.

resolveLogoSrc passes /_next/ URLs through untouched so bundled values
never get double-prefixed with the server root path. The new Logo
molecule owns resolution and the letter-avatar fallback and warns with
the failing URL on load error; ProviderLogo delegates to it. The three
bare img sites in the agents wizard render through Logo, fixing their
broken-image bug.

Dashscope now uses qwen.png, RunwayML the on-disk runway.png, and the
GradientAI entry is removed (no plausible asset exists). soniox.svg and
ai21.svg drop a single mismatched intrinsic dimension attribute that
Turbopack's import-time image parser rejects. Dead logoSrc lookup in
AddModelForm deleted. Vitest resolves image imports to Next's
StaticImageData shape via a config plugin so tests exercise the same
/_next/ URLs as production.

* fix(ui): retry logo load when src changes after an error

Track which src errored instead of a boolean so a Logo instance whose
source changes in place (agents modal title) attempts the new URL
rather than staying on the letter-avatar until remount.
2026-07-21 14:27:36 -07:00

64 lines
1.6 KiB
TypeScript

import { defineConfig, type Plugin, type ViteUserConfig } from "vitest/config";
import { resolve } from "path";
const staticImageData: Plugin = {
name: "next-static-image-data",
enforce: "pre",
load(id: string) {
const path = id.split("?")[0];
if (!/\.(svg|png|jpe?g|gif|webp|avif|ico|bmp)$/i.test(path)) return undefined;
const name = path.slice(path.lastIndexOf("/") + 1);
return `export default { src: ${JSON.stringify(`/_next/static/media/${name}`)}, height: 24, width: 24 };`;
},
};
const config: ViteUserConfig = {
plugins: [staticImageData],
test: {
environment: "jsdom",
setupFiles: ["tests/setupTests.ts"],
globals: true,
css: true, // lets you import CSS/modules without extra mocks
testTimeout: 30000,
silent: process.env.CI ? "passed-only" : false,
teardownTimeout: 60000,
coverage: {
provider: "v8",
reporter: ["text", "lcov"],
include: ["src/**/*.{ts,tsx}"],
exclude: [
"**/*.d.ts",
"**/*.test.*",
"**/*.spec.*",
"tests/**",
"e2e_tests/**",
"node_modules/**",
".next/**",
"out/**",
"**/*.config.*",
"postcss.config.*",
"tailwind.config.*",
"next.config.*",
],
},
exclude: ["e2e_tests/**", "node_modules/**"],
include: ["src/**/*.test.ts", "src/**/*.test.tsx", "tests/**/*.test.ts", "tests/**/*.test.tsx"],
},
resolve: {
alias: {
"@": resolve(__dirname, "src"),
},
},
define: {
"import.meta.vitest": "undefined",
},
esbuild: {
jsx: "automatic",
jsxImportSource: "react",
},
};
export default defineConfig(config);