| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import { NextRequest, NextResponse } from "next/server"; |
|
|
| const API_URL = process.env.D2L_API_URL || "https://etiya-d2l-api.hf.space"; |
| const TOKEN = process.env.HF_TOKEN; |
|
|
| export const dynamic = "force-dynamic"; |
| export const runtime = "nodejs"; |
|
|
| async function forwardRoot(req: NextRequest) { |
| if (!TOKEN) { |
| return NextResponse.json( |
| { |
| error: |
| "HF_TOKEN env var not set on server. Copy .env.example to .env.local and add your token.", |
| }, |
| { status: 500 } |
| ); |
| } |
|
|
| const upstreamUrl = `${API_URL}/${req.nextUrl.search}`; |
|
|
| const upstreamHeaders: Record<string, string> = { |
| Authorization: `Bearer ${TOKEN}`, |
| Accept: "application/json", |
| }; |
|
|
| let body: BodyInit | null = null; |
| if (req.method !== "GET" && req.method !== "HEAD") { |
| const contentType = req.headers.get("content-type") || "application/json"; |
| upstreamHeaders["Content-Type"] = contentType; |
| body = await req.text(); |
| } |
|
|
| let resp: Response; |
| try { |
| resp = await fetch(upstreamUrl, { |
| method: req.method, |
| headers: upstreamHeaders, |
| body, |
| cache: "no-store", |
| }); |
| } catch (e: unknown) { |
| return NextResponse.json( |
| { |
| error: "upstream_unreachable", |
| message: e instanceof Error ? e.message : String(e), |
| upstream: upstreamUrl, |
| }, |
| { status: 502 } |
| ); |
| } |
|
|
| const contentType = resp.headers.get("content-type") || "application/json"; |
| const text = await resp.text(); |
| return new NextResponse(text, { |
| status: resp.status, |
| headers: { "content-type": contentType }, |
| }); |
| } |
|
|
| export const GET = forwardRoot; |
| export const POST = forwardRoot; |
| export const PUT = forwardRoot; |
| export const DELETE = forwardRoot; |
| export const PATCH = forwardRoot; |
|
|