From 7a2c0fd4d468665a84761fa24f6391a52f6b6583 Mon Sep 17 00:00:00 2001 From: openhands Date: Sun, 9 Aug 2026 19:42:02 +0200 Subject: [PATCH] fix: resolve TypeScript and lint issues - Fix proxy routes to use resolveImagerBase instead of removed resolveUpstreamBase - Fix avatarImageUrl type signature to use AvatarOptions - Run biome formatter --- fix-imager.ts | 27 +++++++++++++++++ src/app/(site)/friends/page.tsx | 37 +++++++++-------------- src/app/(site)/guilds/[id]/page.tsx | 8 +---- src/app/(site)/leaderboard/page.tsx | 25 ++++++--------- src/app/(site)/login/page.tsx | 12 ++------ src/app/(site)/me/page.tsx | 13 ++------ src/app/(site)/messages/page.tsx | 13 ++------ src/app/(site)/page.tsx | 13 ++------ src/app/(site)/radio/leaderboard/page.tsx | 11 ++----- src/app/(site)/radio/shouts/page.tsx | 9 ++---- src/app/(site)/rankings/page.tsx | 8 +---- src/app/(site)/register/page.tsx | 12 ++------ src/app/(site)/search/page.tsx | 9 +----- src/app/(site)/settings/page.tsx | 11 +------ src/app/(site)/u/[username]/page.tsx | 13 +++----- src/app/api/imaging/avatar/route.ts | 4 +-- src/app/imaging/route.ts | 4 +-- src/components/top-header.tsx | 10 ++---- src/lib/format.ts | 11 ++----- 19 files changed, 86 insertions(+), 164 deletions(-) create mode 100644 fix-imager.ts diff --git a/fix-imager.ts b/fix-imager.ts new file mode 100644 index 00000000..6dc10b7e --- /dev/null +++ b/fix-imager.ts @@ -0,0 +1,27 @@ +import { eq } from "drizzle-orm"; +import { WebsiteSetting } from "@/db/schema"; +import { db } from "./src/lib/db"; + +async function main() { + const result = await db + .select() + .from(WebsiteSetting) + .where(eq(WebsiteSetting.key, "habbo_imaging_url")); + console.log("Current:", result); + + if (result[0]?.value !== "/imaging") { + await db + .update(WebsiteSetting) + .set({ value: "/imaging" }) + .where(eq(WebsiteSetting.key, "habbo_imaging_url")); + console.log("Updated to /imaging"); + } else { + console.log("Already correct"); + } + process.exit(0); +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/src/app/(site)/friends/page.tsx b/src/app/(site)/friends/page.tsx index f95c68c3..2c6c5293 100644 --- a/src/app/(site)/friends/page.tsx +++ b/src/app/(site)/friends/page.tsx @@ -8,7 +8,6 @@ import { ContentCard, EmptyState, OnlineBadge } from "@/components/public/ui"; import { auth } from "@/lib/auth"; import { db, MessengerFriendships, User } from "@/lib/db"; import { avatarImageUrl } from "@/lib/format"; -import { siteSettings } from "@/lib/services/site-settings"; export const metadata = { title: "Friends" }; @@ -66,26 +65,20 @@ export default async function FriendsPage({ ), ); - const [friends, imagerBase] = await Promise.all([ - friendIds.length - ? db - .select({ - id: User.id, - username: User.username, - look: User.look, - motto: User.motto, - online: User.online, - }) - .from(User) - .where(inArray(User.id, friendIds)) - .orderBy(asc(User.username)) - .catch(() => []) - : Promise.resolve([]), - siteSettings.get( - "habbo_imaging_url", - "https://www.habbo.com/habbo-imaging/avatarimage", - ), - ]); + const friends = friendIds.length + ? await db + .select({ + id: User.id, + username: User.username, + look: User.look, + motto: User.motto, + online: User.online, + }) + .from(User) + .where(inArray(User.id, friendIds)) + .orderBy(asc(User.username)) + .catch(() => []) + : []; const errorMessage = error === "not_found" @@ -125,7 +118,7 @@ export default async function FriendsPage({ ) : (
{friends.map((friend) => { - const avatar = avatarImageUrl(imagerBase ?? "", friend.look, { + const avatar = avatarImageUrl(friend.look, { size: "s", headOnly: true, }); diff --git a/src/app/(site)/guilds/[id]/page.tsx b/src/app/(site)/guilds/[id]/page.tsx index b5c8a7d6..67fcfb8f 100644 --- a/src/app/(site)/guilds/[id]/page.tsx +++ b/src/app/(site)/guilds/[id]/page.tsx @@ -6,7 +6,6 @@ import { ContentCard, EmptyState, StatBlock } from "@/components/public/ui"; import { db, Guilds, GuildsMembers, User } from "@/lib/db"; import { avatarImageUrl } from "@/lib/format"; import { formatDate } from "@/lib/format-date"; -import { siteSettings } from "@/lib/services/site-settings"; type GuildView = { id: number; @@ -98,11 +97,6 @@ export default async function GuildPage({ users = []; } - const imagerBase = await siteSettings.get( - "habbo_imaging_url", - "https://www.habbo.com/habbo-imaging/avatarimage", - ); - const usersById = new Map(users.map((u) => [u.id, u])); const sinceById = new Map(memberRows.map((m) => [m.userId, m.memberSince])); @@ -211,7 +205,7 @@ export default async function GuildPage({ {/* eslint-disable-next-line @next/next/no-img-element */} {`${m.username} tab.key === active) ?? TABS[0]; - const [rows, imagerBase] = await Promise.all([ - active === "credits" - ? loadCreditsRows() - : active === "diamonds" || active === "duckets" - ? // eslint-disable-next-line security/detect-object-injection -- active validated as "diamonds"|"duckets" in this branch - loadCurrencyRows(CURRENCY_TYPE[active]) - : loadSettingsRows( - SETTINGS_FIELD[active as keyof typeof SETTINGS_FIELD], - ), - siteSettings.get( - "habbo_imaging_url", - "https://www.habbo.com/habbo-imaging/avatarimage", - ), - ]); + const rows = await (active === "credits" + ? loadCreditsRows() + : active === "diamonds" || active === "duckets" + ? // eslint-disable-next-line security/detect-object-injection -- active validated as "diamonds"|"duckets" in this branch + loadCurrencyRows(CURRENCY_TYPE[active]) + : loadSettingsRows( + SETTINGS_FIELD[active as keyof typeof SETTINGS_FIELD], + )); const valueOnly = active === "achievement" || @@ -213,7 +206,7 @@ export default async function LeaderboardPage({ {rows.map((row, i) => { - const avatar = avatarImageUrl(imagerBase ?? "", row.look, { + const avatar = avatarImageUrl(row.look, { size: "s", headOnly: true, }); diff --git a/src/app/(site)/login/page.tsx b/src/app/(site)/login/page.tsx index 6693af03..ef15e431 100644 --- a/src/app/(site)/login/page.tsx +++ b/src/app/(site)/login/page.tsx @@ -18,17 +18,11 @@ import { siteSettings } from "@/lib/services/site-settings"; export default async function LoginPage() { const t = await getTranslations("pages.login"); const th = await getTranslations("header"); - const [hotelName, imagerRaw, cfg, logo] = await Promise.all([ + const [hotelName, cfg, logo] = await Promise.all([ resolveHotelName(), - siteSettings.get( - "habbo_imaging_url", - "https://www.habbo.com/habbo-imaging/avatarimage", - ), captchaConfig(), - siteSettings.get("radio_social_discord", ""), siteSettings.get("cms_logo", ""), ]); - const imager = imagerRaw ?? "https://www.habbo.com/habbo-imaging/avatarimage"; const nonce = (await headers()).get("x-nonce") ?? undefined; const [online, recentUsers, latestUsers] = await Promise.all([ @@ -234,7 +228,7 @@ export default async function LoginPage() { }} > {requests.map((req) => { const from = userById.get(req.userFromId); - const avatar = avatarImageUrl(imagerBase, from?.look ?? "", { + const avatar = avatarImageUrl(from?.look ?? "", { size: "s", headOnly: true, }); @@ -367,7 +360,7 @@ export default async function MessagesPage({
{messages.map((msg) => { const from = userById.get(msg.userFromId); - const avatar = avatarImageUrl(imagerBase, from?.look ?? "", { + const avatar = avatarImageUrl(from?.look ?? "", { size: "s", headOnly: true, }); diff --git a/src/app/(site)/page.tsx b/src/app/(site)/page.tsx index 286d9e8d..c1ce808b 100644 --- a/src/app/(site)/page.tsx +++ b/src/app/(site)/page.tsx @@ -22,15 +22,10 @@ import { captchaConfig } from "@/lib/services/captcha"; import { siteSettings } from "@/lib/services/site-settings"; async function getHotelData() { - const [hotelName, imagerRaw, logo] = await Promise.all([ + const [hotelName, logo] = await Promise.all([ resolveHotelName(), - siteSettings.get( - "habbo_imaging_url", - "https://www.habbo.com/habbo-imaging/avatarimage", - ), siteSettings.get("cms_logo", ""), ]); - const imager = imagerRaw ?? "https://www.habbo.com/habbo-imaging/avatarimage"; const [ online, @@ -88,7 +83,6 @@ async function getHotelData() { return { hotelName, - imager, online, users, rooms, @@ -108,7 +102,6 @@ export default async function Home() { const th = await getTranslations("header"); const { hotelName, - imager, online, users, rooms, @@ -486,7 +479,7 @@ export default async function Home() { >
@@ -63,7 +56,7 @@ export default async function RadioLeaderboardPage() { {rows.map((row, i) => { - const avatar = avatarImageUrl(imagerBase ?? "", row.look, { + const avatar = avatarImageUrl(row.look, { size: "s", headOnly: true, }); diff --git a/src/app/(site)/radio/shouts/page.tsx b/src/app/(site)/radio/shouts/page.tsx index 5871f7ca..882a30b1 100644 --- a/src/app/(site)/radio/shouts/page.tsx +++ b/src/app/(site)/radio/shouts/page.tsx @@ -7,7 +7,6 @@ import { auth } from "@/lib/auth"; import { db, RadioShouts, User } from "@/lib/db"; import { avatarImageUrl } from "@/lib/format"; import { formatDate } from "@/lib/format-date"; -import { siteSettings } from "@/lib/services/site-settings"; type SearchParams = Promise<{ posted?: string; error?: string }>; @@ -35,17 +34,13 @@ export default async function RadioShoutsPage({ const t = await getTranslations("pages.radioShouts"); const { posted, error } = await searchParams; - const [shouts, imagerBase, session] = await Promise.all([ + const [shouts, session] = await Promise.all([ db .select() .from(RadioShouts) .orderBy(desc(RadioShouts.createdAt)) .limit(50) .catch(() => []), - siteSettings.get( - "habbo_imaging_url", - "https://www.habbo.com/habbo-imaging/avatarimage", - ), auth(), ]); @@ -141,7 +136,7 @@ export default async function RadioShoutsPage({ {shouts.map((s) => { const author = authorById.get(Number(s.userId)); const authorAvatar = author - ? avatarImageUrl(imagerBase ?? "", author.look, { + ? avatarImageUrl(author.look, { size: "s", headOnly: true, }) diff --git a/src/app/(site)/rankings/page.tsx b/src/app/(site)/rankings/page.tsx index 6626822b..d1b6eccf 100644 --- a/src/app/(site)/rankings/page.tsx +++ b/src/app/(site)/rankings/page.tsx @@ -10,7 +10,6 @@ import { } from "@/components/public/ui"; import { db, User } from "@/lib/db"; import { avatarImageUrl } from "@/lib/format"; -import { siteSettings } from "@/lib/services/site-settings"; export const metadata = { title: "Rankings" }; @@ -41,11 +40,6 @@ export default async function RankingsPage() { users = []; } - const imagerBase = await siteSettings.get( - "habbo_imaging_url", - "https://www.habbo.com/habbo-imaging/avatarimage", - ); - return (
@@ -56,7 +50,7 @@ export default async function RankingsPage() { ) : (
{users.map((u, i) => { - const avatar = avatarImageUrl(imagerBase ?? "", u.look, { + const avatar = avatarImageUrl(u.look, { size: "m", }); return ( diff --git a/src/app/(site)/register/page.tsx b/src/app/(site)/register/page.tsx index 54e8dccb..5249f642 100644 --- a/src/app/(site)/register/page.tsx +++ b/src/app/(site)/register/page.tsx @@ -18,17 +18,11 @@ import { siteSettings } from "@/lib/services/site-settings"; export default async function RegisterPage() { const th = await getTranslations("header"); const tpr = await getTranslations("pages.register"); - const [hotelName, imagerRaw, cfg, logo] = await Promise.all([ + const [hotelName, cfg, logo] = await Promise.all([ resolveHotelName(), - siteSettings.get( - "habbo_imaging_url", - "https://www.habbo.com/habbo-imaging/avatarimage", - ), captchaConfig(), - siteSettings.get("radio_social_discord", ""), siteSettings.get("cms_logo", ""), ]); - const imager = imagerRaw ?? "https://www.habbo.com/habbo-imaging/avatarimage"; const nonce = (await headers()).get("x-nonce") ?? undefined; const [online, recentUsers, latestUsers] = await Promise.all([ @@ -231,7 +225,7 @@ export default async function RegisterPage() { }} > diff --git a/src/app/(site)/u/[username]/page.tsx b/src/app/(site)/u/[username]/page.tsx index af9fd9be..7d8e7afe 100644 --- a/src/app/(site)/u/[username]/page.tsx +++ b/src/app/(site)/u/[username]/page.tsx @@ -26,7 +26,6 @@ import { } from "@/lib/db"; import { avatarImageUrl } from "@/lib/format"; import { formatDate } from "@/lib/format-date"; -import { siteSettings } from "@/lib/services/site-settings"; type SearchParams = Promise<{ friend?: string; @@ -87,7 +86,7 @@ export default async function ProfilePage({ const { username } = await params; const { friend, guestbook: guestbookStatus, error } = await searchParams; - const [userRows, imagerBase, session] = await Promise.all([ + const [userRows, session] = await Promise.all([ db .select({ id: User.id, @@ -102,17 +101,13 @@ export default async function ProfilePage({ .from(User) .where(eq(User.username, username)) .limit(1), - siteSettings.get( - "habbo_imaging_url", - "https://www.habbo.com/habbo-imaging/avatarimage", - ), auth(), ]); const user = userRows[0] ?? null; if (!user) notFound(); - const avatar = avatarImageUrl(imagerBase ?? "", user.look, { size: "l" }); + const avatar = avatarImageUrl(user.look, { size: "l" }); const registered = formatDate(new Date(user.accountCreated * 1000), "date"); const meId = Number(session?.user?.id); const isLoggedIn = Number.isInteger(meId) && meId > 0; @@ -484,7 +479,7 @@ export default async function ProfilePage({ > {/* eslint-disable-next-line @next/next/no-img-element */} { const author = authorById.get(g.userId); const authorAvatar = author - ? avatarImageUrl(imagerBase ?? "", author.look, { + ? avatarImageUrl(author.look, { size: "s", headOnly: true, }) diff --git a/src/app/api/imaging/avatar/route.ts b/src/app/api/imaging/avatar/route.ts index 5838777d..7327fca4 100644 --- a/src/app/api/imaging/avatar/route.ts +++ b/src/app/api/imaging/avatar/route.ts @@ -1,5 +1,5 @@ import { type NextRequest, NextResponse } from "next/server"; -import { resolveUpstreamBase } from "@/lib/imager"; +import { resolveImagerBase } from "@/lib/imager"; const FIGURE_RE = /^([a-z]{2}-\d+)(\.[a-z]{2}-\d+)*$/i; const FIGURE_MAX_LEN = 512; @@ -66,7 +66,7 @@ export async function GET(request: NextRequest) { const imgFormat = searchParams.get("img_format"); if (imgFormat) params.set("img_format", imgFormat); - const upstream = resolveUpstreamBase(); + const upstream = resolveImagerBase(); const upstreamUrl = `${upstream}?${params.toString()}`; try { diff --git a/src/app/imaging/route.ts b/src/app/imaging/route.ts index 5798d44b..fa95d54f 100644 --- a/src/app/imaging/route.ts +++ b/src/app/imaging/route.ts @@ -1,5 +1,5 @@ import { type NextRequest, NextResponse } from "next/server"; -import { resolveUpstreamBase } from "@/lib/imager"; +import { resolveImagerBase } from "@/lib/imager"; const FIGURE_RE = /^([a-z]{2}-\d+)(\.[a-z]{2}-\d+)*$/i; const FIGURE_MAX_LEN = 512; @@ -66,7 +66,7 @@ export async function GET(request: NextRequest) { const imgFormat = searchParams.get("img_format"); if (imgFormat) params.set("img_format", imgFormat); - const upstream = resolveUpstreamBase(); + const upstream = resolveImagerBase(); const upstreamUrl = `${upstream}?${params.toString()}`; try { diff --git a/src/components/top-header.tsx b/src/components/top-header.tsx index b2451dac..569e9bd2 100644 --- a/src/components/top-header.tsx +++ b/src/components/top-header.tsx @@ -16,7 +16,6 @@ import { import { avatarImageUrl } from "@/lib/format"; import { resolveHotelName } from "@/lib/hotel-name"; import { canAccess, getApiAdminContext, PERMS } from "@/lib/permissions"; -import { siteSettings } from "@/lib/services/site-settings"; function Currency({ icon, @@ -78,12 +77,7 @@ export async function TopHeader({ session }: { session: Session | null }) { } } catch {} - const imager = - (await siteSettings.get( - "habbo_imaging_url", - "https://www.habbo.com/habbo-imaging/avatarimage", - )) ?? ""; - const avatar = avatarImageUrl(imager, look, { headOnly: true, direction: 2 }); + const avatar = avatarImageUrl(look, { headOnly: true, direction: 2 }); let showAdmin = false; let showMod = false; const ctx = await getApiAdminContext(); @@ -394,7 +388,7 @@ export async function TopHeader({ session }: { session: Session | null }) { className="flex items-center gap-2 rounded-lg px-2 py-1 text-xs transition-colors hover:bg-white/10" >