feat: implement dashboard state management, API proxy layer, and modular UI components for weather monitoring and payments
This commit is contained in:
@@ -1,4 +1,10 @@
|
||||
import type { NextRequest } from "next/server";
|
||||
import { NextResponse } from "next/server";
|
||||
import {
|
||||
applyAuthResponseCookies,
|
||||
buildBackendRequestHeaders,
|
||||
} from "@/lib/backend-auth";
|
||||
import { buildCachedJsonResponse } from "@/lib/http-cache";
|
||||
|
||||
const PASSTHROUGH_UPSTREAM_STATUSES = new Set([
|
||||
400,
|
||||
@@ -70,3 +76,64 @@ export function buildProxyExceptionResponse(
|
||||
|
||||
return NextResponse.json(body, { status: options.status ?? 500 });
|
||||
}
|
||||
|
||||
export async function proxyBackendJsonGet(
|
||||
req: NextRequest,
|
||||
options: {
|
||||
cacheControl?: string;
|
||||
conditionalResponse?: boolean;
|
||||
detailLimit?: number;
|
||||
error?: string;
|
||||
fetchCache?: RequestCache;
|
||||
includeSupabaseIdentity?: boolean;
|
||||
publicMessage: string;
|
||||
revalidateSeconds?: number;
|
||||
signal?: AbortSignal;
|
||||
statusOnException?: number;
|
||||
timeoutPublicMessage?: string;
|
||||
url: string;
|
||||
},
|
||||
) {
|
||||
let auth: Awaited<ReturnType<typeof buildBackendRequestHeaders>> | null = null;
|
||||
try {
|
||||
auth = await buildBackendRequestHeaders(req, {
|
||||
includeSupabaseIdentity: options.includeSupabaseIdentity ?? false,
|
||||
});
|
||||
const res = await fetch(options.url, {
|
||||
headers: auth.headers,
|
||||
...(options.fetchCache
|
||||
? { cache: options.fetchCache }
|
||||
: { next: { revalidate: options.revalidateSeconds ?? 30 } }),
|
||||
signal: options.signal,
|
||||
});
|
||||
if (!res.ok) {
|
||||
const raw = await res.text();
|
||||
const response = buildUpstreamErrorResponse(res.status, raw, {
|
||||
detailLimit: options.detailLimit,
|
||||
error: options.error,
|
||||
});
|
||||
return applyAuthResponseCookies(response, auth.response);
|
||||
}
|
||||
|
||||
const data = await res.json();
|
||||
const response =
|
||||
options.cacheControl && options.conditionalResponse !== false
|
||||
? buildCachedJsonResponse(req, data, options.cacheControl)
|
||||
: NextResponse.json(data, {
|
||||
headers: options.cacheControl
|
||||
? { "Cache-Control": options.cacheControl }
|
||||
: undefined,
|
||||
});
|
||||
return applyAuthResponseCookies(response, auth.response);
|
||||
} catch (error) {
|
||||
const timedOut = options.signal?.aborted === true;
|
||||
const response = buildProxyExceptionResponse(error, {
|
||||
publicMessage:
|
||||
timedOut && options.timeoutPublicMessage
|
||||
? options.timeoutPublicMessage
|
||||
: options.publicMessage,
|
||||
status: timedOut ? 504 : options.statusOnException,
|
||||
});
|
||||
return auth ? applyAuthResponseCookies(response, auth.response) : response;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user