Your Name f6b7758ec9
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
feat: extend lovart rebuild with blog and changelog experiences
2026-02-12 12:11:47 +08:00

133 lines
3.6 KiB
TypeScript

import { type NextRequest, NextResponse } from "next/server";
import {
getPublicChangelogEvents,
getEnabledAiModelsWithProvider,
getNavLinks,
getPublicFeaturedImages,
getPublicFeaturedRanking,
getSiteSettings,
getTutorialVideos,
} from "@/lib/db/queries";
function formatProviderStats(models: Awaited<ReturnType<typeof getEnabledAiModelsWithProvider>>) {
const providerMap = new Map<string, number>();
for (const item of models) {
const providerName = item.provider.name;
providerMap.set(providerName, (providerMap.get(providerName) ?? 0) + 1);
}
return Array.from(providerMap.entries()).map(([name, count]) => ({ name, count }));
}
export async function GET(request: NextRequest) {
try {
const view = request.nextUrl.searchParams.get("view") || "home";
const [settings, navLinks, models, videos] = await Promise.all([
getSiteSettings(),
getNavLinks(),
getEnabledAiModelsWithProvider(),
getTutorialVideos(),
]);
if (view === "pricing") {
const featuredImages = await getPublicFeaturedImages(8);
const response = NextResponse.json({
view,
settings,
pricing: {
models: models.length,
tutorials: videos.length,
featuredSamples: featuredImages,
},
});
response.headers.set("Cache-Control", "public, s-maxage=60, stale-while-revalidate=300");
return response;
}
if (view === "news") {
const [featuredImages, ranking] = await Promise.all([
getPublicFeaturedImages(12),
settings.rankingEnabled ? getPublicFeaturedRanking(6) : Promise.resolve([]),
]);
const response = NextResponse.json({
view,
settings,
news: {
videos,
featuredImages,
ranking,
},
});
response.headers.set("Cache-Control", "public, s-maxage=60, stale-while-revalidate=300");
return response;
}
if (view === "blog") {
const featuredImages = await getPublicFeaturedImages(8);
const response = NextResponse.json({
view,
settings,
blog: {
videos,
featuredImages,
},
});
response.headers.set("Cache-Control", "public, s-maxage=60, stale-while-revalidate=300");
return response;
}
if (view === "changelog") {
const [events, ranking] = await Promise.all([
getPublicChangelogEvents(18),
settings.rankingEnabled ? getPublicFeaturedRanking(6) : Promise.resolve([]),
]);
const response = NextResponse.json({
view,
settings,
changelog: {
events,
ranking,
},
});
response.headers.set("Cache-Control", "public, s-maxage=60, stale-while-revalidate=300");
return response;
}
const [featuredImages, ranking] = await Promise.all([
getPublicFeaturedImages(12),
settings.rankingEnabled ? getPublicFeaturedRanking(5) : Promise.resolve([]),
]);
const response = NextResponse.json({
view: "home",
settings,
navLinks,
providers: formatProviderStats(models),
stats: {
modelCount: models.length,
tutorialCount: videos.length,
featuredCount: featuredImages.length,
},
featuredImages,
ranking,
videos: settings.tutorialEnabled ? videos : [],
});
response.headers.set("Cache-Control", "public, s-maxage=60, stale-while-revalidate=300");
return response;
} catch (error) {
console.error("[Public Lovart API] Error:", error);
return NextResponse.json({ error: "Failed to fetch Lovart public payload" }, { status: 500 });
}
}