Refactor TypeScript interfaces and types for improved readability and consistency
Gitea Auto Deploy / Deploy-Container (push) Failing after 13m19s
Gitea Auto Deploy / Deploy-Container (push) Failing after 13m19s
- Reformatted interfaces in changelog.ts, enka.ts, extraData.ts, global.d.ts, index.ts, lightconeDetail.ts, metaData.ts, mics.ts, mocDetail.ts, modelConfig.ts, monsterDetail.ts, peakDetail.ts, pfDetail.ts, psConnect.ts, relicDetail.ts, showcase.ts, srtools.ts, and zod/index.ts for consistent indentation and spacing. - Added missing imports and interfaces where necessary, such as Invasion in mocDetail.ts and peakDetail.ts. - Ensured all interfaces are properly structured and maintain a consistent style across the codebase.
This commit is contained in:
@@ -1,25 +1,25 @@
|
||||
import { getDataCache } from "@/lib/cache/cache"
|
||||
|
||||
export async function GET(
|
||||
req: Request,
|
||||
{ params }: { params: Promise<{ name: string }> }
|
||||
) {
|
||||
const { name } = await params
|
||||
|
||||
const item = getDataCache(name)
|
||||
|
||||
if (!item) {
|
||||
return new Response("Not found", { status: 404 })
|
||||
}
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
"Content-Type": "application/json",
|
||||
"Cache-Control": "public, max-age=3600"
|
||||
}
|
||||
|
||||
if (item.type === "br") {
|
||||
headers["Content-Encoding"] = "br"
|
||||
}
|
||||
|
||||
return new Response(new Uint8Array(item.buf), { headers })
|
||||
import { getDataCache } from "@/lib/cache/cache"
|
||||
|
||||
export async function GET(
|
||||
req: Request,
|
||||
{ params }: { params: Promise<{ name: string }> }
|
||||
) {
|
||||
const { name } = await params
|
||||
|
||||
const item = getDataCache(name)
|
||||
|
||||
if (!item) {
|
||||
return new Response("Not found", { status: 404 })
|
||||
}
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
"Content-Type": "application/json",
|
||||
"Cache-Control": "public, max-age=3600"
|
||||
}
|
||||
|
||||
if (item.type === "br") {
|
||||
headers["Content-Encoding"] = "br"
|
||||
}
|
||||
|
||||
return new Response(new Uint8Array(item.buf), { headers })
|
||||
}
|
||||
+70
-70
@@ -1,79 +1,79 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import axios from 'axios'
|
||||
import net from 'net'
|
||||
|
||||
function isPrivateHost(hostname: string): boolean {
|
||||
if (
|
||||
hostname === 'localhost' ||
|
||||
hostname.startsWith('127.') ||
|
||||
hostname.startsWith('10.') ||
|
||||
hostname.startsWith('192.168.') ||
|
||||
/^172\.(1[6-9]|2[0-9]|3[0-1])\./.test(hostname)
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (net.isIP(hostname)) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
try {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const targetUrl = searchParams.get("url")
|
||||
if (!targetUrl) {
|
||||
return NextResponse.json({ error: "Missing url" }, { status: 400 })
|
||||
}
|
||||
|
||||
const response = await fetch(targetUrl)
|
||||
|
||||
if (!response.ok) {
|
||||
return NextResponse.json({ error: "Failed to fetch image" }, { status: 500 })
|
||||
}
|
||||
|
||||
const buffer = await response.arrayBuffer()
|
||||
|
||||
return new NextResponse(buffer, {
|
||||
headers: {
|
||||
"Content-Type": response.headers.get("content-type") || "image/png",
|
||||
"Cache-Control": "public, max-age=3600",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
},
|
||||
})
|
||||
} catch (e: unknown) {
|
||||
return NextResponse.json({ error: (e as Error)?.message }, { status: 500 })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function isPrivateHost(hostname: string): boolean {
|
||||
if (
|
||||
hostname === 'localhost' ||
|
||||
hostname.startsWith('127.') ||
|
||||
hostname.startsWith('10.') ||
|
||||
hostname.startsWith('192.168.') ||
|
||||
/^172\.(1[6-9]|2[0-9]|3[0-1])\./.test(hostname)
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (net.isIP(hostname)) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
try {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const targetUrl = searchParams.get("url")
|
||||
if (!targetUrl) {
|
||||
return NextResponse.json({ error: "Missing url" }, { status: 400 })
|
||||
}
|
||||
|
||||
const response = await fetch(targetUrl)
|
||||
|
||||
if (!response.ok) {
|
||||
return NextResponse.json({ error: "Failed to fetch image" }, { status: 500 })
|
||||
}
|
||||
|
||||
const buffer = await response.arrayBuffer()
|
||||
|
||||
return new NextResponse(buffer, {
|
||||
headers: {
|
||||
"Content-Type": response.headers.get("content-type") || "image/png",
|
||||
"Cache-Control": "public, max-age=3600",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
},
|
||||
})
|
||||
} catch (e: unknown) {
|
||||
return NextResponse.json({ error: (e as Error)?.message }, { status: 500 })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
const body = await request.json()
|
||||
const { serverUrl, method, ...payload } = body
|
||||
|
||||
if (!serverUrl) {
|
||||
return NextResponse.json({ error: 'Missing serverUrl' }, { status: 400 })
|
||||
}
|
||||
if (!method) {
|
||||
return NextResponse.json({ error: 'Missing method' }, { status: 400 })
|
||||
}
|
||||
|
||||
let url = serverUrl.trim()
|
||||
if (!url.startsWith('http://') && !url.startsWith('https://')) {
|
||||
url = `http://${url}`
|
||||
}
|
||||
|
||||
const parsed = new URL(url)
|
||||
if (isPrivateHost(parsed.hostname)) {
|
||||
return NextResponse.json(
|
||||
{ error: `Connection to private/internal address (${parsed.hostname}) is not allowed` },
|
||||
{ status: 403 }
|
||||
)
|
||||
}
|
||||
|
||||
const { serverUrl, method, ...payload } = body
|
||||
|
||||
if (!serverUrl) {
|
||||
return NextResponse.json({ error: 'Missing serverUrl' }, { status: 400 })
|
||||
}
|
||||
if (!method) {
|
||||
return NextResponse.json({ error: 'Missing method' }, { status: 400 })
|
||||
}
|
||||
|
||||
let url = serverUrl.trim()
|
||||
if (!url.startsWith('http://') && !url.startsWith('https://')) {
|
||||
url = `http://${url}`
|
||||
}
|
||||
|
||||
const parsed = new URL(url)
|
||||
if (isPrivateHost(parsed.hostname)) {
|
||||
return NextResponse.json(
|
||||
{ error: `Connection to private/internal address (${parsed.hostname}) is not allowed` },
|
||||
{ status: 403 }
|
||||
)
|
||||
}
|
||||
|
||||
let response
|
||||
|
||||
switch (method.toUpperCase()) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
"use client"
|
||||
import EidolonsInfo from "@/components/eidolonsInfo";
|
||||
export default function EidolonsInfoPage() {
|
||||
return (
|
||||
<div className="w-full">
|
||||
<EidolonsInfo/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
"use client"
|
||||
import EidolonsInfo from "@/components/eidolonsInfo";
|
||||
export default function EidolonsInfoPage() {
|
||||
return (
|
||||
<div className="w-full">
|
||||
<EidolonsInfo/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
+80
-8
@@ -1,6 +1,5 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
|
||||
@plugin "daisyui" {
|
||||
exclude: properties;
|
||||
themes: winter --default, night --prefersdark, cupcake, coffee;
|
||||
@@ -9,19 +8,19 @@
|
||||
@tailwind utilities;
|
||||
|
||||
@plugin 'tailwind-scrollbar' {
|
||||
nocompatible: true;
|
||||
nocompatible: true;
|
||||
}
|
||||
|
||||
|
||||
:root {
|
||||
--size-big: 4vw;
|
||||
--size-medium: 3vw;
|
||||
--size-small: 2vw;
|
||||
}
|
||||
|
||||
/* Smooth Modern Ultra-Sleek Scrollbars */
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
@@ -29,10 +28,83 @@
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #9ca3af;
|
||||
border-radius: 0;
|
||||
background: rgba(156, 163, 175, 0.28);
|
||||
border-radius: 9999px;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(156, 163, 175, 0.55);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-button {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Custom UI Utilities for Gaming Companion Aesthetic */
|
||||
@layer utilities {
|
||||
.glass-card {
|
||||
background-color: var(--color-base-100);
|
||||
border: 1px solid color-mix(in srgb, var(--color-base-content) 10%, transparent);
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.glass-panel {
|
||||
background-color: var(--color-base-100);
|
||||
border: 1px solid color-mix(in srgb, var(--color-base-content) 10%, transparent);
|
||||
}
|
||||
|
||||
.hover-lift {
|
||||
transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.25s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.25s ease;
|
||||
}
|
||||
.hover-lift:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.active-press {
|
||||
transition: transform 0.15s cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
.active-press:active {
|
||||
transform: scale(0.97);
|
||||
}
|
||||
|
||||
/* Rarity Glow Effects */
|
||||
.glow-5star {
|
||||
box-shadow: 0 0 16px -2px rgba(245, 158, 11, 0.35);
|
||||
}
|
||||
|
||||
.glow-4star {
|
||||
box-shadow: 0 0 16px -2px rgba(168, 85, 247, 0.35);
|
||||
}
|
||||
|
||||
/* Ambient Background - Clean Canvas */
|
||||
.bg-ambient-mesh {
|
||||
background-color: var(--color-base-100);
|
||||
}
|
||||
|
||||
/* Theme Adaptive Path & Stat Icon Filters - High Accessibility Contrast */
|
||||
.theme-path-icon {
|
||||
filter: brightness(0.2) opacity(0.85);
|
||||
}
|
||||
[data-theme="night"] .theme-path-icon,
|
||||
[data-theme="coffee"] .theme-path-icon {
|
||||
filter: brightness(0.8) opacity(0.85);
|
||||
}
|
||||
.theme-path-icon-active {
|
||||
filter: brightness(0);
|
||||
}
|
||||
[data-theme="night"] .theme-path-icon-active,
|
||||
[data-theme="coffee"] .theme-path-icon-active {
|
||||
filter: brightness(1);
|
||||
}
|
||||
|
||||
/* Stat icons (HSR raw sprite icons are white pngs, need dark filter on light themes) */
|
||||
.theme-stat-icon {
|
||||
filter: brightness(0.15) opacity(0.8);
|
||||
}
|
||||
[data-theme="night"] .theme-stat-icon,
|
||||
[data-theme="coffee"] .theme-stat-icon {
|
||||
filter: brightness(0.95) opacity(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-10
@@ -64,9 +64,9 @@ export default async function RootLayout({
|
||||
const locale = await getLocale()
|
||||
|
||||
return (
|
||||
<html lang={locale} suppressHydrationWarning>
|
||||
<html lang={locale} suppressHydrationWarning className="overflow-x-hidden">
|
||||
<body
|
||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||
className={`${geistSans.variable} ${geistMono.variable} antialiased overflow-x-hidden max-w-full`}
|
||||
suppressHydrationWarning
|
||||
>
|
||||
<NextIntlClientProvider messages={messages}>
|
||||
@@ -74,17 +74,19 @@ export default async function RootLayout({
|
||||
<ThemeProvider>
|
||||
<ClientThemeWrapper>
|
||||
<ClientDataFetcher >
|
||||
<div className="min-h-screen w-full">
|
||||
<div className="min-h-screen w-full flex flex-col justify-between bg-ambient-mesh selection:bg-primary/20 selection:text-primary">
|
||||
<Header />
|
||||
<div className="grid grid-cols-12 w-full">
|
||||
<div className="hidden sm:block md:col-span-4 lg:col-span-3 sticky top-0 self-start h-fit">
|
||||
<main className="grid grid-cols-12 w-full flex-1">
|
||||
<aside className="hidden sm:block sm:col-span-4 md:col-span-4 lg:col-span-3 sticky top-16 self-start h-[calc(100vh-4rem)] overflow-hidden border-r border-base-content/10 bg-base-100/30 backdrop-blur-sm">
|
||||
<AvatarBar />
|
||||
</div>
|
||||
<div className="col-span-12 sm:col-span-8 lg:col-span-9">
|
||||
</aside>
|
||||
<section className="col-span-12 sm:col-span-8 md:col-span-8 lg:col-span-9 flex flex-col min-w-0">
|
||||
<ActionBar />
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 p-2 sm:p-3 sm:pt-1">
|
||||
{children}
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
"use client";
|
||||
|
||||
import RelicsInfo from "@/components/relicsInfo";
|
||||
|
||||
export default function RelicsInfoPage() {
|
||||
return (
|
||||
<div className="w-full">
|
||||
<RelicsInfo></RelicsInfo>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
"use client";
|
||||
|
||||
import RelicsInfo from "@/components/relicsInfo";
|
||||
|
||||
export default function RelicsInfoPage() {
|
||||
return (
|
||||
<div className="w-full">
|
||||
<RelicsInfo></RelicsInfo>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
"use client"
|
||||
|
||||
import ShowCaseInfo from "@/components/showcaseCard"
|
||||
|
||||
export default function ShowcaseCard() {
|
||||
return (
|
||||
<div>
|
||||
<ShowCaseInfo />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
"use client"
|
||||
|
||||
import ShowCaseInfo from "@/components/showcaseCard"
|
||||
|
||||
export default function ShowcaseCard() {
|
||||
return (
|
||||
<div>
|
||||
<ShowCaseInfo />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
"use client";
|
||||
|
||||
import SkillsInfo from "@/components/skillsInfo";
|
||||
|
||||
export default function SkillsInfoPage() {
|
||||
return (
|
||||
<div className="w-full">
|
||||
<SkillsInfo></SkillsInfo>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
"use client";
|
||||
|
||||
import SkillsInfo from "@/components/skillsInfo";
|
||||
|
||||
export default function SkillsInfoPage() {
|
||||
return (
|
||||
<div className="w-full">
|
||||
<SkillsInfo></SkillsInfo>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user