Download app/api/proxy/route.ts from Etiya/d2l-ui: direct link, hf CLI and curl.
- Browser
- Download file 2.1 kB
-
https://huggingface.co/spaces/Etiya/d2l-ui/resolve/main/app/api/proxy/route.ts
- Command line
-
hf download hf://spaces/Etiya/d2l-ui/app/api/proxy/route.ts
-
curl -L -o route.ts https://huggingface.co/spaces/Etiya/d2l-ui/resolve/main/app/api/proxy/route.ts
2.1 kB
| /** | |
| * Sibling route to `[...path]/route.ts` that handles the upstream root | |
| * (`GET /` on the backend — health/summary). | |
| * | |
| * Why: Next 15's catch-all segment `[...path]` does not match an empty | |
| * path, so `fetch("/api/proxy/")` 308-redirects to `/api/proxy` and 404s. | |
| * `lib/api.ts` calls `health()` as `request("")`, which lands here. | |
| */ | |
| 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; | |