Skip to content

Commit 97354d6

Browse files
committed
feat: fetch patch resource exist external api
1 parent 3eb32a7 commit 97354d6

File tree

2 files changed

+154
-0
lines changed

2 files changed

+154
-0
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import { NextRequest, NextResponse } from 'next/server'
2+
import { prisma } from '~/prisma/index'
3+
import { kunRateLimiter } from '~/lib/reteLimiter'
4+
import { getRemoteIp } from '~/app/api/utils/getRemoteIp'
5+
6+
const DOMAIN_PATTERNS = [
7+
/^http:\/\/localhost:\d+$/,
8+
/^http:\/\/127.0.0.1:\d+$/,
9+
/^https:\/\/([\w-]+\.)*touchgal\.us$/
10+
]
11+
12+
const RATE_LIMIT_MAX = 10
13+
const RATE_LIMIT_WINDOW_MS = 60 * 60 * 1000
14+
15+
interface MoyuResponse<T> {
16+
success: boolean
17+
message: string
18+
data: T | null
19+
}
20+
21+
export const GET = async (
22+
request: NextRequest
23+
): Promise<NextResponse<MoyuResponse<string[]>>> => {
24+
const origin = request.headers.get('origin') ?? ''
25+
const isAllowedOrigin = origin
26+
? DOMAIN_PATTERNS.some((pattern) => pattern.test(origin))
27+
: false
28+
const corsHeaders = {
29+
'Access-Control-Allow-Origin': isAllowedOrigin ? origin : '',
30+
'Access-Control-Allow-Methods': 'GET, OPTIONS',
31+
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
32+
'Access-Control-Expose-Headers':
33+
'X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset'
34+
}
35+
const ip = getRemoteIp(request.headers)
36+
const rateLimitResult = await kunRateLimiter({
37+
windowMs: RATE_LIMIT_WINDOW_MS,
38+
max: RATE_LIMIT_MAX,
39+
message: 'Too many requests, please try again later.',
40+
identifier: `${ip}:${origin || 'unknown'}`
41+
})
42+
const headers = {
43+
'Content-Type': 'application/json',
44+
'X-RateLimit-Limit': rateLimitResult.limit.toString(),
45+
'X-RateLimit-Remaining': rateLimitResult.remaining.toString(),
46+
'X-RateLimit-Reset': rateLimitResult.reset.toString(),
47+
...corsHeaders
48+
}
49+
if (request.method === 'OPTIONS') {
50+
return new NextResponse(null, { headers: corsHeaders })
51+
}
52+
if (!rateLimitResult.success) {
53+
return NextResponse.json(
54+
{
55+
success: false,
56+
message: 'Rate limit exceeded. Please try again later.',
57+
data: null
58+
},
59+
{ status: 429, headers }
60+
)
61+
}
62+
63+
try {
64+
const patchesWithResource = await prisma.patch.findMany({
65+
where: {
66+
vndb_id: { not: null },
67+
resource: {
68+
some: {}
69+
}
70+
},
71+
select: {
72+
vndb_id: true
73+
}
74+
})
75+
76+
const vndbIdArray: string[] = patchesWithResource.map((p) => p.vndb_id!)
77+
78+
return NextResponse.json(
79+
{
80+
success: true,
81+
message: 'success',
82+
data: vndbIdArray
83+
},
84+
{ status: 200, headers }
85+
)
86+
} catch (error) {
87+
const errorMessage = error instanceof Error ? error.message : String(error)
88+
return NextResponse.json(
89+
{
90+
success: false,
91+
message: `An error occurred while processing your request: ${errorMessage}`,
92+
data: null
93+
},
94+
{ status: 500, headers }
95+
)
96+
}
97+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
export interface KunUser {
2+
id: number
3+
name: string
4+
avatar: string
5+
}
6+
7+
export interface KunPatchResponse {
8+
id: number
9+
name: string
10+
// e.g. "vndb_id": "v19658",
11+
vndb_id: string
12+
banner: string
13+
introduction: string
14+
// e.g. "released": "2016-11-25",
15+
released: string
16+
status: number
17+
download: number
18+
view: number
19+
resource_update_time: Date
20+
type: string[]
21+
language: string[]
22+
engine: string[]
23+
platform: string[]
24+
user_id: number
25+
user: KunUser
26+
created: Date
27+
updated: Date
28+
resource: KunPatchResourceResponse[]
29+
}
30+
31+
export interface KunPatchResourceResponse {
32+
id: number
33+
storage: 's3' | 'user'
34+
name: string
35+
model_name: string
36+
size: string
37+
code: string
38+
password: string
39+
note: string
40+
hash: string
41+
type: string[]
42+
language: string[]
43+
platform: string[]
44+
download: number
45+
status: number
46+
update_time: Date
47+
user_id: number
48+
patch_id: number
49+
created: Date
50+
user: KunUser
51+
}
52+
53+
export interface HikariResponse {
54+
success: boolean
55+
message: string
56+
data: KunPatchResponse | null
57+
}

0 commit comments

Comments
 (0)