69 lines
1.9 KiB
TypeScript
69 lines
1.9 KiB
TypeScript
import { NextResponse } from "next/server";
|
|
|
|
const SPRING_BASE =
|
|
process.env.SPRING_BASE_URL ?? "http://battlbuilder-api:8080";
|
|
|
|
function forwardHeaders(req: Request) {
|
|
const headers = new Headers();
|
|
const auth = req.headers.get("authorization");
|
|
const cookie = req.headers.get("cookie");
|
|
|
|
if (auth) headers.set("authorization", auth);
|
|
if (cookie) headers.set("cookie", cookie);
|
|
|
|
headers.set("accept", "application/json");
|
|
return headers;
|
|
}
|
|
|
|
type SpringProxyOptions<TBody> = {
|
|
method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
body?: TBody;
|
|
cache?: RequestCache;
|
|
};
|
|
|
|
export async function springProxy<TResponse, TBody = never>(
|
|
req: Request,
|
|
path: string,
|
|
options?: SpringProxyOptions<TBody>
|
|
) {
|
|
const url = `${SPRING_BASE}${path}`;
|
|
const headers = forwardHeaders(req);
|
|
|
|
const init: RequestInit = {
|
|
method: options?.method ?? "GET",
|
|
headers,
|
|
cache: options?.cache ?? "no-store",
|
|
};
|
|
|
|
if (options && "body" in options && options.body !== undefined) {
|
|
headers.set("content-type", "application/json");
|
|
init.body = JSON.stringify(options.body);
|
|
}
|
|
|
|
const res = await fetch(url, init);
|
|
|
|
// If Spring returns 204 No Content, don't try to parse JSON
|
|
if (res.status === 204) {
|
|
return new NextResponse(null, { status: 204 });
|
|
}
|
|
|
|
const contentType = res.headers.get("content-type") ?? "";
|
|
let payload: unknown;
|
|
|
|
if (contentType.includes("application/json")) {
|
|
payload = await res.json().catch(() => null);
|
|
} else {
|
|
payload = await res.text().catch(() => null);
|
|
}
|
|
|
|
// If Spring returned JSON, we respond JSON; otherwise text
|
|
if (typeof payload === "string") {
|
|
return new NextResponse(payload, {
|
|
status: res.status,
|
|
headers: { "content-type": contentType || "text/plain" },
|
|
});
|
|
}
|
|
|
|
return NextResponse.json(payload as TResponse, { status: res.status });
|
|
}
|